feat: ✨ 热门推荐页
This commit is contained in:
parent
21b9783bf8
commit
8f538dd197
@ -51,7 +51,7 @@
|
|||||||
{
|
{
|
||||||
"path": "pages/hot/hot",
|
"path": "pages/hot/hot",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "hot"
|
"navigationBarTitleText": "热门推荐"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,225 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="hot">hot</view>
|
<view class="viewport">
|
||||||
|
<!-- 推荐封面图 -->
|
||||||
|
<view class="cover">
|
||||||
|
<image :src="bannerPic"></image>
|
||||||
|
</view>
|
||||||
|
<template>
|
||||||
|
<!-- 推荐选项 -->
|
||||||
|
<view class="tabs">
|
||||||
|
<text
|
||||||
|
:class="['text', { active: index === actived }]"
|
||||||
|
v-for="(subTypeItem, index) in subTypes"
|
||||||
|
:key="subTypeItem.id"
|
||||||
|
@tap="actived = index"
|
||||||
|
>{{ subTypeItem.title }}</text
|
||||||
|
>
|
||||||
|
</view>
|
||||||
|
<!-- 推荐列表 -->
|
||||||
|
<scroll-view
|
||||||
|
:scroll-y="true"
|
||||||
|
class="scroll-view"
|
||||||
|
@scrolltolower="onScrollToLower"
|
||||||
|
v-for="(subTypeItem, index) in subTypes"
|
||||||
|
v-show="actived === index"
|
||||||
|
:key="subTypeItem.id"
|
||||||
|
>
|
||||||
|
<view class="goods">
|
||||||
|
<navigator
|
||||||
|
hover-class="none"
|
||||||
|
class="navigator"
|
||||||
|
v-for="goodItem in subTypeItem.goodsItems.items"
|
||||||
|
:key="goodItem.id"
|
||||||
|
:url="`/pages/goods/goods?id=${goodItem.id}`"
|
||||||
|
>
|
||||||
|
<image class="thumb" :src="goodItem.picture"></image>
|
||||||
|
<view class="name ellipsis">{{ goodItem.desc }}</view>
|
||||||
|
<view class="price">
|
||||||
|
<text class="symbol">¥</text>
|
||||||
|
<text class="number">{{ goodItem.price }}</text>
|
||||||
|
</view>
|
||||||
|
</navigator>
|
||||||
|
</view>
|
||||||
|
<view class="loading-text">{{
|
||||||
|
subTypeItem.goodsItems.page === subTypeItem.goodsItems.pages
|
||||||
|
? '没有更多数据~'
|
||||||
|
: '正在加载...'
|
||||||
|
}}</view>
|
||||||
|
</scroll-view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup></script>
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { getHotRecommend } from '@/services/hot'
|
||||||
|
import type { SubTypeItem } from '@/types/hot'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
<style lang="scss"></style>
|
// 热门推荐页 标题和url
|
||||||
|
const hotMap = {
|
||||||
|
'1': { title: '特惠推荐', url: '/hot/preference' },
|
||||||
|
'2': { title: '爆款推荐', url: '/hot/inVogue' },
|
||||||
|
'3': { title: '一站买全', url: '/hot/oneStop' },
|
||||||
|
'4': { title: '新鲜好物', url: '/hot/new' },
|
||||||
|
}
|
||||||
|
|
||||||
|
// uni-app获取路由参数
|
||||||
|
const query = defineProps<{
|
||||||
|
type: string
|
||||||
|
}>()
|
||||||
|
|
||||||
|
// 热门类型
|
||||||
|
const currHot = hotMap[query.type as keyof typeof hotMap]
|
||||||
|
// 动态设置标题
|
||||||
|
uni.setNavigationBarTitle({ title: currHot!.title })
|
||||||
|
|
||||||
|
// 推荐封面图
|
||||||
|
const bannerPic = ref('')
|
||||||
|
// 分类列表
|
||||||
|
const subTypes = ref<SubTypeItem[]>([])
|
||||||
|
|
||||||
|
// 当前选中的分类id
|
||||||
|
const actived = ref(0)
|
||||||
|
|
||||||
|
// 获取热门商品, 不传subType, 获取所有分类第一页
|
||||||
|
const getRecommend = async () => {
|
||||||
|
const res = await getHotRecommend(currHot!.url, {
|
||||||
|
page: import.meta.env.DEV ? 33 : 1,
|
||||||
|
pageSize: 10,
|
||||||
|
})
|
||||||
|
bannerPic.value = res.result.bannerPicture
|
||||||
|
subTypes.value = res.result.subTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
// 滚动到底部
|
||||||
|
const onScrollToLower = async () => {
|
||||||
|
// 只追加当前tab的数据
|
||||||
|
const subTypeId = subTypes.value[actived.value].id
|
||||||
|
const { page, pages, pageSize } = subTypes.value[actived.value].goodsItems
|
||||||
|
// 没有更多数据
|
||||||
|
if (page === pages) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '没有更多数据~',
|
||||||
|
icon: 'none',
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const nextPage = page + 1
|
||||||
|
// 接口被复用了, 没有传的subType, 没有返回 goodsItems 数据
|
||||||
|
const res = await getHotRecommend(currHot!.url, {
|
||||||
|
subType: subTypeId,
|
||||||
|
page: nextPage,
|
||||||
|
pageSize,
|
||||||
|
})
|
||||||
|
// 追加数据
|
||||||
|
subTypes.value[actived.value].goodsItems.items.push(
|
||||||
|
...res.result.subTypes[actived.value].goodsItems.items,
|
||||||
|
)
|
||||||
|
subTypes.value[actived.value].goodsItems.page = nextPage
|
||||||
|
}
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getRecommend()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
height: 100%;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
}
|
||||||
|
.viewport {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
padding: 180rpx 0 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.cover {
|
||||||
|
width: 750rpx;
|
||||||
|
height: 225rpx;
|
||||||
|
border-radius: 0 0 40rpx 40rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.scroll-view {
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
height: 100rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
margin: 0 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
box-shadow: 0 4rpx 5rpx rgba(200, 200, 200, 0.3);
|
||||||
|
color: #333;
|
||||||
|
background-color: #fff;
|
||||||
|
position: relative;
|
||||||
|
z-index: 9;
|
||||||
|
.text {
|
||||||
|
margin: 0 20rpx;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.active {
|
||||||
|
&::after {
|
||||||
|
content: '';
|
||||||
|
width: 40rpx;
|
||||||
|
height: 4rpx;
|
||||||
|
transform: translate(-50%);
|
||||||
|
background-color: #27ba9b;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
bottom: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.goods {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 20rpx 20rpx;
|
||||||
|
.navigator {
|
||||||
|
width: calc(50% - 50rpx);
|
||||||
|
padding: 20rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
.thumb {
|
||||||
|
width: 305rpx;
|
||||||
|
height: 305rpx;
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
height: 88rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
.price {
|
||||||
|
line-height: 1;
|
||||||
|
color: #cf4444;
|
||||||
|
font-size: 30rpx;
|
||||||
|
}
|
||||||
|
.symbol {
|
||||||
|
font-size: 70%;
|
||||||
|
}
|
||||||
|
.decimal {
|
||||||
|
font-size: 70%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
padding: 20rpx 0 50rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
18
src/services/hot.ts
Normal file
18
src/services/hot.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { http } from '@/utils/http'
|
||||||
|
import type { PageParams, PageResult } from '@/types/global'
|
||||||
|
import type { HotResult } from '@/types/hot'
|
||||||
|
|
||||||
|
type HotParams = PageParams & {
|
||||||
|
// 推荐列表 Tab 项的 id, 默认查询全部 Tab 项的第 1 页数据
|
||||||
|
subType?: string
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 获取热门推荐
|
||||||
|
*/
|
||||||
|
export const getHotRecommend = (url: string, data: HotParams) => {
|
||||||
|
return http<HotResult>({
|
||||||
|
url,
|
||||||
|
method: 'GET',
|
||||||
|
data,
|
||||||
|
})
|
||||||
|
}
|
23
src/types/hot.d.ts
vendored
Normal file
23
src/types/hot.d.ts
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import type { PageResult, GoodsItem } from './global'
|
||||||
|
|
||||||
|
/** 热门推荐-子类选项 */
|
||||||
|
export type SubTypeItem = {
|
||||||
|
/** 子类id */
|
||||||
|
id: string
|
||||||
|
/** 子类标题 */
|
||||||
|
title: string
|
||||||
|
/** 子类对应的商品集合 */
|
||||||
|
goodsItems: PageResult<GoodsItem>
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 热门推荐 */
|
||||||
|
export type HotResult = {
|
||||||
|
/** id信息 */
|
||||||
|
id: string
|
||||||
|
/** 活动图片 */
|
||||||
|
bannerPicture: string
|
||||||
|
/** 活动标题 */
|
||||||
|
title: string
|
||||||
|
/** 子类选项 */
|
||||||
|
subTypes: SubTypeItem[]
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user