index.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. <!-- 使用 type="home" 属性设置首页,其他页面不需要设置,默认为page;推荐使用json5,更强大,且允许注释 -->
  2. <route lang="json5" type="home">
  3. {
  4. layout: 'tabbar',
  5. style: {
  6. // 'custom' 表示开启自定义导航栏,默认 'default'
  7. navigationStyle: 'custom',
  8. },
  9. }
  10. </route>
  11. <script lang="ts" setup>
  12. // 必须导入需要用到的页面生命周期(即使在当前页面上没有直接使用到)
  13. // eslint-disable-next-line unused-imports/no-unused-imports
  14. import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
  15. import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging.js'
  16. import { getList } from '@/api/product'
  17. import { toPage } from '@/utils/page'
  18. defineOptions({
  19. name: 'Index', // 首页
  20. })
  21. // 获取屏幕边界到安全区域距离
  22. const systemInfo = uni.getSystemInfoSync()
  23. const safeAreaInsets = systemInfo.safeAreaInsets
  24. // z-paging
  25. const paging = ref(null)
  26. // 类似mixins,如果是页面滚动务必要写这一行,并传入当前ref绑定的paging,注意此处是paging,而非paging.value
  27. useZPaging(paging)
  28. // 搜索
  29. function toSearch() {
  30. uni.navigateTo({
  31. url: '/pages/search/search',
  32. })
  33. }
  34. // 轮播图
  35. const current = ref<number>(0)
  36. const swiperList = ref([
  37. 'https://picsum.photos/750/420?random=1',
  38. 'https://picsum.photos/750/420?random=2',
  39. 'https://picsum.photos/750/420?random=3',
  40. 'https://picsum.photos/750/420?random=4',
  41. ])
  42. function handleClick(e) {
  43. // console.log(e)
  44. }
  45. function onChange(e) {
  46. // console.log(e)
  47. }
  48. // 导航图标
  49. const navIcons = ref([
  50. {
  51. image: '/static/icons/home-vip.png',
  52. title: 'home.missionCenter',
  53. size: '100rpx',
  54. url: '/pages/missionCenter/missionCenter',
  55. },
  56. {
  57. image: '/static/icons/home-vip.png',
  58. title: 'home.refer&earn',
  59. size: '100rpx',
  60. url: '/pages/referEarn/referEarn',
  61. },
  62. {
  63. image: '/static/icons/home-vip.png',
  64. title: 'home.vip',
  65. size: '112rpx',
  66. url: '/pages/vipMembership/vipMembership',
  67. },
  68. {
  69. image: '/static/icons/home-vip.png',
  70. title: 'home.bestSellers',
  71. size: '100rpx',
  72. url: '/pages/bestSellers/bestSellers',
  73. },
  74. {
  75. image: '/static/icons/home-vip.png',
  76. title: 'home.topChampions',
  77. size: '100rpx',
  78. url: '/pages/topChampions/topChampions',
  79. },
  80. ])
  81. // 新品列表
  82. const newProducts = ref<any>([])
  83. async function getNewList() {
  84. const res = await getList({ page: 1, size: 10, isNew: true })
  85. console.log(res)
  86. newProducts.value = res.data.list
  87. }
  88. // 商品列表
  89. const priceTab = ref<number>(0)
  90. // 300Spot 500Spot 1000Spot 2000Spot
  91. const priceTabList = ref([
  92. {
  93. title: '300Spot',
  94. value: 300,
  95. minPrice: 0,
  96. maxPrice: 300,
  97. },
  98. {
  99. title: '500Spot',
  100. value: 500,
  101. minPrice: 300,
  102. maxPrice: 500,
  103. },
  104. {
  105. title: '1000Spot',
  106. value: 1000,
  107. minPrice: 500,
  108. maxPrice: 1000,
  109. },
  110. {
  111. title: '2000Spot',
  112. value: 2000,
  113. minPrice: 1000,
  114. maxPrice: 2000,
  115. },
  116. ])
  117. const dataList = ref<any>([])
  118. async function queryList(pageNo, pageSize) {
  119. // 获取当前选中tab的价格范围,默认为第一个tab (0-300)
  120. const currentTab = priceTabList.value[priceTab.value] || priceTabList.value[0]
  121. const minPrice = currentTab?.minPrice ?? 0
  122. const maxPrice = currentTab?.maxPrice ?? 300
  123. const params = {
  124. page: pageNo,
  125. size: pageSize,
  126. minPrice,
  127. maxPrice,
  128. }
  129. const res = await getList(params)
  130. paging.value.complete(res.data.list)
  131. }
  132. // 价格tab切换事件
  133. function onPriceTabChange() {
  134. paging.value.reload()
  135. }
  136. onLoad(() => {
  137. getNewList()
  138. })
  139. </script>
  140. <template>
  141. <z-paging ref="paging" v-model="dataList" bg-color="#fff" use-page-scroll @query="queryList">
  142. <template #top>
  143. <view
  144. class="flex items-center justify-between bg-white pb-40rpx pl-42rpx pr-34rpx pt-26rpx"
  145. :style="{ paddingTop: `${safeAreaInsets?.top + 13}px` }"
  146. >
  147. <image src="/static/header-logo.png" class="h-54rpx w-250rpx" />
  148. <view class="flex items-center">
  149. <wd-icon custom-class="mr-20rpx" name="search1" size="38rpx" @click="toSearch" />
  150. <wd-icon name="notification" size="38rpx" @click="toPage('/pages/notifications/notifications')" />
  151. </view>
  152. </view>
  153. </template>
  154. <wd-swiper
  155. v-model:current="current"
  156. :list="swiperList" autoplay
  157. :indicator="{ type: 'fraction' }"
  158. indicator-position="bottom-right"
  159. @click="handleClick"
  160. @change="onChange"
  161. />
  162. <view class="px-24rpx pb-24rpx">
  163. <view class="flex items-end justify-between pb-22rpx pt-24rpx">
  164. <view v-for="(item, index) in navIcons" :key="index" class="flex flex-col items-center" @click="toPage(item.url)">
  165. <image :src="item.image" :style="`width: ${item.size}; height: ${item.size};`" />
  166. <view class="mt-14rpx text-center text-22rpx text-#898989 font-bold">
  167. {{ $t(item.title) }}
  168. </view>
  169. </view>
  170. </view>
  171. <view>
  172. <view class="mb-16rpx text-32rpx">
  173. News
  174. </view>
  175. <scroll-view scroll-x>
  176. <view class="flex items-center gap-22rpx pb-24rpx">
  177. <product v-for="(item, index) in newProducts" :key="index" :item="item" @item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId, id: item.id })" />
  178. </view>
  179. </scroll-view>
  180. </view>
  181. <view>
  182. <wd-tabs v-model="priceTab" :line-width="0" :line-height="0" @change="onPriceTabChange">
  183. <template v-for="item in priceTabList" :key="item">
  184. <wd-tab :title="item.title" />
  185. </template>
  186. </wd-tabs>
  187. <view class="grid grid-cols-2 gap-22rpx">
  188. <product v-for="(item, index) in dataList" :key="index" width="100%" :height="340" :item="item" @item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId, id: item.id })" />
  189. </view>
  190. </view>
  191. </view>
  192. </z-paging>
  193. </template>
  194. <style>
  195. page {
  196. background: #fff;
  197. }
  198. </style>