UniappDay03

1.热门推荐-准备工作

复制代码
// 用defineProps获取页面参数,query
const query = defineProps<{
  type: string
}>()
const currHot = hotMap.find((v) => v.type === query.type)
// 动态设置标题
uni.setNavigationBarTitle({ title: currHot!.title })
</script>

2.获取热门推荐数据

PageParams & { subType: string } 交叉类型,基于原有类型上进行扩展,再作为当前数据类型

  1. 封装通用接口

    import type { PageParams } from '@/types/global'
    import { http } from '@/utils/http'

    // 拓展类型
    type HotParams = PageParams & { subType: string }
    export const getHotRecommendAPI = (url: string, data: HotParams) => {
    return http({
    method: 'GET',
    url,
    data,
    })
    }

  2. 初始化调用

    // 获取热门推荐数据
    const getHotRecommendData = async () => {
    const res = await getHotRecommendAPI(currHot!.url)
    }
    // 页面加载时调用
    onLoad(() => {
    getHotRecommendData()
    })

3.类型定义

类型的复用

复制代码
export type GuessItem = GoodsItem


import type { PageResult, GoodsItem } from './global'
/** 热门推荐 */
export type HotResult = {
  /** id信息 */
  id: string
  /** 活动图片 */
  bannerPicture: string
  /** 活动标题 */
  title: string
  /** 子类选项 */
  subTypes: SubTypeItem[]
}

/** 热门推荐-子类选项 */
export type SubTypeItem = {
  /** 子类id */
  id: string
  /** 子类标题 */
  title: string
  /** 子类对应的商品集合 */
  goodsItems: PageResult<GoodsItem>
}



type HotParams = PageParams & { subType: string }
export const getHotRecommendAPI = (url: string, data?: HotParams) => {
  return http<HotResult>({
    method: 'GET',
    url,
    data,
  })
}
4.渲染页面和Tab交互
  1. 渲染页面

    // 推荐封面图
    const bannnerPicture = ref('')
    // 推荐选项
    const subTypes = ref<SubTypeItem[]>([])
    // 获取下标
    const activeIndex = ref(0)
    // 获取热门推荐数据
    const getHotRecommendData = async () => {
    const res = await getHotRecommendAPI(currHot!.url)
    bannnerPicture.value = res.result.bannerPicture
    subTypes.value = res.result.subTypes
    }

  2. Tab交互

    <text
    v-for="(item, index) in subTypes"
    :key="item.id"
    class="text"
    :class="{ active: index === activeIndex }"
    @tap="activeIndex = index"
    >{{ item.title }}</text >

用v-show反复的切换更好而不用v-if 耗费性能

复制代码
<!-- 推荐列表 -->
    <scroll-view
      v-for="(item, index) in subTypes"
      :key="item.id"
      v-show="activeIndex === index"
      scroll-y
      class="scroll-view"
    >
      <view class="goods">
        <navigator
          hover-class="none"
          class="navigator"
          v-for="goods in item.goodsItems.items"
          :key="goods.id"
          :url="`/pages/goods/goods?id=${goods.id}`"
        >
          <image class="thumb" :src="goods.picture"></image>
          <view class="name ellipsis">{{ goods.name }}</view>
          <view class="price">
            <text class="symbol">¥</text>
            <text class="number">{{ goods.price }}</text>
          </view>
        </navigator>
      </view>
      <view class="loading-text">正在加载...</view>
    </scroll-view>
  </view>
</template>

5.分页加载

  1. 滚动触底
  2. 获取当前选项
  3. 当前页码累加
  4. 调用API传参
  5. 当前数据追加

实现效果:

复制代码
// 滚动触底
const onScrolltolower = async () => {
  //获取当前选项
  const currsubTypes = subTypes.value[activeIndex.value]
  // 当前页码累加
  currsubTypes.goodsItems.page++
  // 调用API传参
  const res = await getHotRecommendAPI(currHot!.url, {
    subType: currsubTypes.id,
    page: currsubTypes.goodsItems.page,
    pageSize: currsubTypes.goodsItems.pageSize,
  })
  // 新的列表选项
  const newSubTypes = res.result.subTypes[activeIndex.value]
  // 数组追加
  currsubTypes.goodsItems.items.push(...newSubTypes.goodsItems.items)
}

6.分页结束条件

分页条件

复制代码
 // 分页条件
  if (currsubTypes.goodsItems.page < currsubTypes.goodsItems.pages) {
    // 当前页码累加
    currsubTypes.goodsItems.page++
  } else {
    // 标志已结束
    currsubTypes.finish = true
    return uni.showToast({ title: '已经到底了' })
  }

标记已结束

复制代码
修改一下:
// 给SubTypeItem 再加一个类型,可有可无加?
const subTypes = ref<(SubTypeItem & { finish?: boolean })[]>([])


// 获取热门推荐数据
const getHotRecommendData = async () => {
  const res = await getHotRecommendAPI(currHot!.url, {
    subType: '912000341',
    // 技巧: 环境变量,开发环境,修改初始页面方便测试分页结果
    page: import.meta.env.DEV ? 30 : 1,
    pageSize: 10,
  })
  bannnerPicture.value = res.result.bannerPicture
  subTypes.value = res.result.subTypes
}


// 标志已结束
    currsubTypes.finish = true
    return uni.showToast({ title: '已经到底了' })

页面底部提示

复制代码
 <view class="loading-text">{{ item.finish ? '已经到底了' : '正在加载中...' }}</view>

技巧:

环境变量,开发环境,修改初始页面方便测试分页结果

page: import.meta.env.DEV ? 30 : 1,

7.准备工作

静态数据=>获取轮播图数据=>渲染轮播图

复制代码
<script setup lang="ts">
import { getHomeBannerAPI } from '@/services/home'
import { BannerItem } from '@/types/home'
import { ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
const bannerList = ref<BannerItem[]>([])
//获取轮播图数据
const getHomeBannerData = async () => {
  const res = await getHomeBannerAPI()
}
// 页面加载时调用
onLoad(() => {
  getHomeBannerData()
})
</script>

8.渲染一级分类和Tab交互

  1. 封装API

    import { http } from '@/utils/http'
    import { CategoryTopItem } from '@/types/category'

    export const getCategoryTopAPI = () => {
    return http<CategoryTopItem[]>({
    method: 'GET',
    url: '/category/top',
    })
    }

  2. 初始化调用

    // 获取分类列表数据
    const getCategoryTopData = async () => {
    const res = await getCategoryTopAPI()
    }

    // 页面加载时调用
    onLoad(() => {
    getHomeBannerData()
    getCategoryTopData()
    })

  3. 定义类型

    // 获取分类列表数据
    const cayegoryList = ref<CategoryTopItem[]>([])
    const getCategoryTopData = async () => {
    const res = await getCategoryTopAPI()
    cayegoryList.value = res.result
    }

  4. 渲染一级分类

    <scroll-view class="primary" scroll-y> <view v-for="(item, index) in cayegoryList" :key="item.id" class="item" :class="{ active: index === activeIndex }" >
  5. Tab交互

    // 获取分类列表数据
    const cayegoryList = ref<CategoryTopItem[]>([])
    const activeIndex = ref(0)
    const getCategoryTopData = async () => {
    const res = await getCategoryTopAPI()
    cayegoryList.value = res.result
    }

    <scroll-view class="primary" scroll-y> <view v-for="(item, index) in cayegoryList" :key="item.id" class="item" :class="{ active: index === activeIndex }" @tap="activeIndex = index" >

9.二级分类和商品渲染

  1. 提取当前二级分类数据

    // 提取当前二级分类数据
    const subCategoryList = computed(() => {
    return cayegoryList.value[activeIndex.value]?.children || []
    })

  2. 渲染二级分类

  3. 渲染商品

    <view class="panel" v-for="item in subCategoryList" :key="item.id"> <view class="title"> <text class="name">{{ item.name }}</text> <navigator class="more" hover-class="none">全部</navigator> </view> <view class="section"> <navigator v-for="goods in item.goods" :key="goods.id" class="goods" hover-class="none" :url="`/pages/goods/goods?id=${goods.id}`" > <image class="image" :src="goods.picture"></image> <view class="name ellipsis">{{ goods.name }}</view> <view class="price"> <text class="symbol">¥</text> <text class="number">{{ goods.price }}</text> </view> </navigator> </view> </view>
相关推荐
Britney⁺♛&?ꪶꪫꪜꫀ2 小时前
Vue2上
vue.js·npm
江城开朗的豌豆2 小时前
Element UI动态组件样式修改小妙招,轻松拿捏!
前端·javascript·vue.js
耶啵奶膘3 小时前
uniapp+vue3——通知栏标题纵向滚动切换
uni-app
海天胜景5 小时前
vue3 el-table 列数据合计
前端·javascript·vue.js
征尘bjajmd5 小时前
vue+element-ui实现主子表
javascript·vue.js·elementui
帧栈5 小时前
开发避坑短篇(6):Vue+Element UI 深度选择器实现表单元素精准对齐的技术实践
vue.js·ui·elementui
小毛驴8506 小时前
典型的 Vue 3 项目目录结构详解
前端·javascript·vue.js
半生过往6 小时前
Vue 项目动态接口获取翻译数据实现方案(前端处理语言翻译 vue-i18n)
前端·javascript·vue.js·i18n
yume_sibai6 小时前
Vue 插槽
前端·javascript·vue.js