Q3学习计划
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

189 lines
3.9 KiB

  1. <template>
  2. <view class="viewport">
  3. <!-- 推荐封面图 -->
  4. <view class="cover">
  5. <image class="image" mode="widthFix" :src="bannerPicture"></image>
  6. </view>
  7. <!-- 推荐选项 -->
  8. <view class="tabs">
  9. <text
  10. v-for="(item, index) in subTypes"
  11. :key="item.id"
  12. class="text"
  13. :class="{ active: index === activeIndex }"
  14. @tap="activeIndex = index"
  15. >{{ item.title }}</text
  16. >
  17. </view>
  18. <!-- 推荐列表 -->
  19. <scroll-view
  20. v-for="(item, index) in subTypes"
  21. :key="item.id"
  22. v-show="activeIndex === index"
  23. scroll-y
  24. class="scroll-view"
  25. >
  26. <view class="goods">
  27. <navigator
  28. hover-class="none"
  29. class="navigator"
  30. v-for="goods in item.goodsItems.items"
  31. :key="goods.id"
  32. :url="`/pages/goods/goods?id=`"
  33. >
  34. <image class="thumb" :src="goods.picture"></image>
  35. <view class="price">
  36. <text class="symbol">¥</text>
  37. <text class="number">{{ goods.price }}</text>
  38. </view>
  39. </navigator>
  40. </view>
  41. <view class="loading-text">正在加载...</view>
  42. </scroll-view>
  43. </view>
  44. </template>
  45. <script setup lang="ts">
  46. import { getHotRecommendAPI } from '@/services/hot'
  47. import { onLoad } from '@dcloudio/uni-app'
  48. import { ref } from 'vue'
  49. import type { SubTypeItem } from '@/types/hot'
  50. // 热门推荐页 标题和url
  51. const hotMap = [
  52. { type: '1', title: '特惠推荐', url: '/hot/preference' },
  53. { type: '2', title: '爆款推荐', url: '/hot/inVogue' },
  54. { type: '3', title: '一站买全', url: '/hot/oneStop' },
  55. { type: '4', title: '新鲜好物', url: '/hot/new' },
  56. ]
  57. // uniapp 获取页面参数
  58. const query = defineProps<{
  59. type: string
  60. }>()
  61. // console.log(query)
  62. const currUrlMap = hotMap.find((v) => v.type === query.type)
  63. // 动态设置标题
  64. uni.setNavigationBarTitle({ title: currUrlMap!.title })
  65. // 推荐封面图
  66. const bannerPicture = ref('')
  67. // 推荐选项
  68. const subTypes = ref<SubTypeItem[]>([])
  69. // 高亮的下标
  70. const activeIndex = ref(0)
  71. // 获取热门推荐数据
  72. const getHotRecommendData = async () => {
  73. const res = await getHotRecommendAPI(currUrlMap!.url)
  74. bannerPicture.value = res.result.bannerPicture
  75. subTypes.value = res.result.subTypes
  76. }
  77. // 页面加载
  78. onLoad(() => {
  79. getHotRecommendData()
  80. })
  81. </script>
  82. <style lang="scss">
  83. page {
  84. height: 100%;
  85. background-color: #f4f4f4;
  86. }
  87. .viewport {
  88. display: flex;
  89. flex-direction: column;
  90. height: 100%;
  91. padding: 180rpx 0 0;
  92. position: relative;
  93. }
  94. .cover {
  95. width: 750rpx;
  96. height: 225rpx;
  97. border-radius: 0 0 40rpx 40rpx;
  98. overflow: hidden;
  99. position: absolute;
  100. left: 0;
  101. top: 0;
  102. .image {
  103. width: 750rpx;
  104. }
  105. }
  106. .scroll-view {
  107. flex: 1;
  108. }
  109. .tabs {
  110. display: flex;
  111. justify-content: space-evenly;
  112. height: 100rpx;
  113. line-height: 90rpx;
  114. margin: 0 20rpx;
  115. font-size: 28rpx;
  116. border-radius: 10rpx;
  117. box-shadow: 0 4rpx 5rpx rgba(200, 200, 200, 0.3);
  118. color: #333;
  119. background-color: #fff;
  120. position: relative;
  121. z-index: 9;
  122. .text {
  123. margin: 0 20rpx;
  124. position: relative;
  125. }
  126. .active {
  127. &::after {
  128. content: '';
  129. width: 40rpx;
  130. height: 4rpx;
  131. transform: translate(-50%);
  132. background-color: #27ba9b;
  133. position: absolute;
  134. left: 50%;
  135. bottom: 24rpx;
  136. }
  137. }
  138. }
  139. .goods {
  140. display: flex;
  141. flex-wrap: wrap;
  142. justify-content: space-between;
  143. padding: 0 20rpx 20rpx;
  144. .navigator {
  145. width: 345rpx;
  146. padding: 20rpx;
  147. margin-top: 20rpx;
  148. border-radius: 10rpx;
  149. background-color: #fff;
  150. }
  151. .thumb {
  152. width: 305rpx;
  153. height: 305rpx;
  154. }
  155. .name {
  156. height: 88rpx;
  157. font-size: 26rpx;
  158. }
  159. .price {
  160. line-height: 1;
  161. color: #cf4444;
  162. font-size: 30rpx;
  163. }
  164. .symbol {
  165. font-size: 70%;
  166. }
  167. .decimal {
  168. font-size: 70%;
  169. }
  170. }
  171. .loading-text {
  172. text-align: center;
  173. font-size: 28rpx;
  174. color: #666;
  175. padding: 20rpx 0 50rpx;
  176. }
  177. </style>