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 }}

用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. 渲染一级分类

  5. Tab交互

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

9.二级分类和商品渲染

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

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

  2. 渲染二级分类

  3. 渲染商品

    {{ item.name }} 全部 {{ goods.name }} ¥ {{ goods.price }}
相关推荐
如果超人不会飞2 小时前
TinyVue Pager分页组件使用指南
前端·vue.js
大刚测试开发实战2 小时前
TestHub重磅更新!AI用例生成增加流式输出、Markdown文档上传、模型配置检测、AI评审开关控制...
vue.js·后端·github
脱脱克克3 小时前
使用 TRAE / VS Code + DeepSeek V4 开发微信小程序、网页
微信小程序·ai编程·环境配置
2501_915921433 小时前
uni-app 上架 iOS 的完整流程(无需依赖 Mac)
android·macos·ios·小程序·uni-app·iphone·webview
可别3903 小时前
Vue 极简实现语音实时转写(录音转文字,低网络依赖、开箱即用)
前端·javascript·vue.js
阿猫的故乡3 小时前
Vue插槽从入门到项目实战:默认插槽、具名插槽、作用域插槽,一次讲明白
前端·javascript·vue.js
前端 贾公子3 小时前
使用 wxappUnpacker 工具进行 MAC 微信小程序反编译
macos·微信小程序·小程序
向日的葵0064 小时前
vue3路由的replace属性(四)
前端·javascript·vue.js·vue路由
阿猫的故乡4 小时前
Vue模板引用和组件暴露:ref拿DOM、defineExpose调方法,案例多到眼花
前端·javascript·vue.js
薛定谔的猫-菜鸟程序员4 小时前
从Electron到Tauri,Rust+Vue(Tauri) 实现超高性能桌面日志应用开发,以及开发避坑指南
vue.js·rust·electron