多 Tabs 分页加载
需要根据当前用户选中的 Tabs 加载对应的列表数据。
Tabs 交互基础
当用户点击页面中的 Tab 后,切换展示相应的商品列表,功能相对简单,快速实现即可。
参考代码
<script setup lang="ts">
// 高亮的下标
const activeIndex = ref(0)
</script>
<template>
<!-- 推荐选项 -->
<view class="tabs">
<text
class="text"
v-for="(item, index) in subTypes"
:key="item.id"
:class="{ active: index === activeIndex }"
@tap="activeIndex = index"
>
{{ item.title }}
</text>
</view>
<!-- 推荐列表 -->
<scroll-view
scroll-y
class="scroll-view"
v-for="(item, index) in subTypes"
:key="item.id"
v-show="activeIndex === index"
>
...省略
</scroll-view>
</template>
加载选中 Tabs 分页数据
根据当前用户选中的 Tabs 加载对应的列表数据。
操作流程
- 根据高亮下标,获取对应列表数据
- 提取列表的分页参数,用于发送请求
- 滚动触底事件,页码累加,数组追加,退出判断等业务和常规分页基本一致
参考代码(总)
热门推荐页
<script setup lang="ts">
import { getHotRecommendAPI } from '@/services/hot'
import type { SubTypeItem } from '@/types/hot'
import { onLoad } from '@dcloudio/uni-app'
import { ref } from 'vue'
// 热门推荐页 标题和url
const hotMap = [
{ type: '1', title: '特惠推荐', url: '/hot/preference' },
{ type: '2', title: '爆款推荐', url: '/hot/inVogue' },
{ type: '3', title: '一站买全', url: '/hot/oneStop' },
{ type: '4', title: '新鲜好物', url: '/hot/new' },
]
// uniapp 获取页面参数
const query = defineProps<{
type: string
}>()
// 获取当前推荐信息
const currHot = hotMap.find((v) => v.type === query.type)
// 动态设置标题
uni.setNavigationBarTitle({ title: currHot!.title })
// 推荐封面图
const bannerPicture = ref('')
// 推荐选项
const subTypes = ref<(SubTypeItem & { finish?: boolean })[]>([])
// 高亮的下标
const activeIndex = ref(0)
// 获取热门推荐数据
const getHotRecommendData = async () => {
const res = await getHotRecommendAPI(currHot!.url, {
// 技巧:环境变量,开发环境,修改初始页面方便测试分页结束
page: import.meta.env.DEV ? 30 : 1,
pageSize: 10,
})
// 保存封面
bannerPicture.value = res.result.bannerPicture
// 保存列表
subTypes.value = res.result.subTypes
}
// 页面加载
onLoad(() => {
getHotRecommendData()
})
// 滚动触底
const onScrolltolower = async () => {
// 获取当前选项
const currsubTypes = subTypes.value[activeIndex.value]
// 分页条件
if (currsubTypes.goodsItems.page < currsubTypes.goodsItems.pages) {
// 当前页码累加
currsubTypes.goodsItems.page++
} else {
// 标记已结束
currsubTypes.finish = true
// 退出并轻提示
return uni.showToast({ icon: 'none', title: '没有更多数据了~' })
}
// 调用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)
}
</script>
<template>
<view class="viewport">
<!-- 推荐封面图 -->
<view class="cover">
<image :src="bannerPicture"></image>
</view>
<!-- 推荐选项 -->
<view class="tabs">
<text
v-for="(item, index) in subTypes"
:key="item.id"
class="text"
:class="{ active: index === activeIndex }"
@tap="activeIndex = index"
>{{ item.title }}</text
>
</view>
<!-- 推荐列表 -->
<scroll-view
v-for="(item, index) in subTypes"
:key="item.id"
v-show="activeIndex === index"
scroll-y
class="scroll-view"
@scrolltolower="onScrolltolower"
>
<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">
{{ item.finish ? '没有更多数据了~' : '正在加载...' }}
</view>
</scroll-view>
</view>
</template>