6 changed files with 261 additions and 16 deletions
-
7src/pages.json
-
189src/pages/hot/hot.vue
-
20src/services/hot.ts
-
18src/types/global.d.ts
-
20src/types/home.d.ts
-
23src/types/hot.d.ts
@ -0,0 +1,189 @@ |
|||
<template> |
|||
<view class="viewport"> |
|||
<!-- 推荐封面图 --> |
|||
<view class="cover"> |
|||
<image class="image" mode="widthFix" :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" |
|||
> |
|||
<view class="goods"> |
|||
<navigator |
|||
hover-class="none" |
|||
class="navigator" |
|||
v-for="goods in item.goodsItems.items" |
|||
:key="goods.id" |
|||
:url="`/pages/goods/goods?id=`" |
|||
> |
|||
<image class="thumb" :src="goods.picture"></image> |
|||
<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> |
|||
|
|||
<script setup lang="ts"> |
|||
import { getHotRecommendAPI } from '@/services/hot' |
|||
import { onLoad } from '@dcloudio/uni-app' |
|||
import { ref } from 'vue' |
|||
import type { SubTypeItem } from '@/types/hot' |
|||
|
|||
// 热门推荐页 标题和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 |
|||
}>() |
|||
|
|||
// console.log(query) |
|||
const currUrlMap = hotMap.find((v) => v.type === query.type) |
|||
|
|||
// 动态设置标题 |
|||
uni.setNavigationBarTitle({ title: currUrlMap!.title }) |
|||
|
|||
// 推荐封面图 |
|||
const bannerPicture = ref('') |
|||
|
|||
// 推荐选项 |
|||
const subTypes = ref<SubTypeItem[]>([]) |
|||
|
|||
// 高亮的下标 |
|||
const activeIndex = ref(0) |
|||
|
|||
// 获取热门推荐数据 |
|||
const getHotRecommendData = async () => { |
|||
const res = await getHotRecommendAPI(currUrlMap!.url) |
|||
bannerPicture.value = res.result.bannerPicture |
|||
subTypes.value = res.result.subTypes |
|||
} |
|||
|
|||
// 页面加载 |
|||
onLoad(() => { |
|||
getHotRecommendData() |
|||
}) |
|||
</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: 750rpx; |
|||
} |
|||
} |
|||
.scroll-view { |
|||
flex: 1; |
|||
} |
|||
.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: 345rpx; |
|||
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> |
@ -0,0 +1,20 @@ |
|||
import { http } from '@/utils/http' |
|||
import type { PageParams } from '@/types/global' |
|||
import type { HotResult } from '@/types/hot' |
|||
|
|||
type HotParams = PageParams & { |
|||
/** Tab 项的 id,默认查询全部 Tab 项的第 1 页数据 */ |
|||
subType?: string |
|||
} |
|||
/** |
|||
* 通用热门推荐类型 |
|||
* @param url 请求地址 |
|||
* @param data 请求参数 |
|||
*/ |
|||
export const getHotRecommendAPI = (url: string, data?: HotParams) => { |
|||
return http<HotResult>({ |
|||
method: 'GET', |
|||
url, |
|||
data, |
|||
}) |
|||
} |
@ -0,0 +1,23 @@ |
|||
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> |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue