index.vue 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  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. defineOptions({
  17. name: 'Index', // 首页
  18. })
  19. // 获取屏幕边界到安全区域距离
  20. const systemInfo = uni.getSystemInfoSync()
  21. const safeAreaInsets = systemInfo.safeAreaInsets
  22. // z-paging
  23. const paging = ref(null)
  24. // 类似mixins,如果是页面滚动务必要写这一行,并传入当前ref绑定的paging,注意此处是paging,而非paging.value
  25. useZPaging(paging)
  26. // 搜索
  27. function toSearch() {
  28. uni.navigateTo({
  29. url: '/pages/search/search',
  30. })
  31. }
  32. // 轮播图
  33. const current = ref<number>(0)
  34. const swiperList = ref([
  35. 'https://picsum.photos/750/420?random=1',
  36. 'https://picsum.photos/750/420?random=2',
  37. 'https://picsum.photos/750/420?random=3',
  38. 'https://picsum.photos/750/420?random=4',
  39. ])
  40. function handleClick(e) {
  41. // console.log(e)
  42. }
  43. function onChange(e) {
  44. // console.log(e)
  45. }
  46. // 导航图标
  47. const navIcons = ref([
  48. {
  49. image: '/static/icons/home-vip.png',
  50. title: 'home.missionCenter',
  51. size: '100rpx',
  52. url: '/pages/missionCenter/missionCenter',
  53. },
  54. {
  55. image: '/static/icons/home-vip.png',
  56. title: 'home.refer&earn',
  57. size: '100rpx',
  58. url: '/pages/referEarn/referEarn',
  59. },
  60. {
  61. image: '/static/icons/home-vip.png',
  62. title: 'home.vip',
  63. size: '112rpx',
  64. url: '/pages/vipMembership/vipMembership',
  65. },
  66. {
  67. image: '/static/icons/home-vip.png',
  68. title: 'home.bestSellers',
  69. size: '100rpx',
  70. url: '/pages/bestSellers/bestSellers',
  71. },
  72. {
  73. image: '/static/icons/home-vip.png',
  74. title: 'home.topChampions',
  75. size: '100rpx',
  76. url: '/pages/topChampions/topChampions',
  77. },
  78. ])
  79. function toPage(url: string) {
  80. if (url) {
  81. uni.navigateTo({
  82. url,
  83. })
  84. }
  85. }
  86. // 新品列表
  87. const newProducts = ref([
  88. {
  89. image: 'https://picsum.photos/260?random=1',
  90. title: 'Chanel Rouge Coco Shine…',
  91. price: '123',
  92. sold: 100,
  93. },
  94. {
  95. image: 'https://picsum.photos/260?random=2',
  96. title: 'Chanel Rouge Coco Shine…',
  97. price: '123',
  98. sold: 100,
  99. },
  100. {
  101. image: 'https://picsum.photos/260?random=3',
  102. title: 'Chanel Rouge Coco Shine…',
  103. price: '123',
  104. sold: 100,
  105. },
  106. {
  107. image: 'https://picsum.photos/260?random=4',
  108. title: 'Chanel Rouge Coco Shine…',
  109. price: '123',
  110. sold: 100,
  111. },
  112. {
  113. image: 'https://picsum.photos/260?random=5',
  114. title: 'Chanel Rouge Coco Shine…',
  115. price: '123',
  116. sold: 100,
  117. },
  118. ])
  119. // 商品列表
  120. const priceTab = ref<number>(0)
  121. // 300Spot 500Spot 1000Spot 2000Spot
  122. const priceTabList = ref([
  123. {
  124. title: '300Spot',
  125. value: 300,
  126. },
  127. {
  128. title: '500Spot',
  129. value: 500,
  130. },
  131. {
  132. title: '1000Spot',
  133. value: 1000,
  134. },
  135. {
  136. title: '2000Spot',
  137. value: 2000,
  138. },
  139. ])
  140. const dataList = ref([])
  141. function queryList(pageNo, pageSize) {
  142. // 此处请求仅为演示,请替换为自己项目中的请求
  143. setTimeout(() => {
  144. dataList.value = [
  145. { title: '123' },
  146. { title: '123' },
  147. { title: '123' },
  148. { title: '12345' },
  149. ]
  150. paging.value.complete(dataList.value)
  151. }, 1000)
  152. }
  153. function toProductDetail(item) {
  154. const data = JSON.stringify({ id: item.id })
  155. uni.navigateTo({
  156. url: `/pages/productDetail/productDetail?data=${encodeURIComponent(data)}`,
  157. })
  158. }
  159. function toNotifications() {
  160. uni.navigateTo({
  161. url: '/pages/notifications/notifications',
  162. })
  163. }
  164. </script>
  165. <template>
  166. <z-paging ref="paging" refresher-only use-page-scroll @query="queryList">
  167. <template #top>
  168. <view
  169. class="flex items-center justify-between bg-white pb-40rpx pl-42rpx pr-34rpx pt-26rpx"
  170. :style="{ paddingTop: `${safeAreaInsets?.top + 13}px` }"
  171. >
  172. <image src="/static/header-logo.png" class="h-54rpx w-250rpx" />
  173. <view class="flex items-center">
  174. <wd-icon custom-class="mr-20rpx" name="search1" size="38rpx" @click="toSearch" />
  175. <wd-icon name="notification" size="38rpx" @click="toNotifications" />
  176. </view>
  177. </view>
  178. </template>
  179. <wd-swiper
  180. v-model:current="current"
  181. :list="swiperList" autoplay
  182. :indicator="{ type: 'fraction' }"
  183. indicator-position="bottom-right"
  184. @click="handleClick"
  185. @change="onChange"
  186. />
  187. <view class="px-24rpx pb-24rpx">
  188. <view class="flex items-end justify-between pb-22rpx pt-24rpx">
  189. <view v-for="(item, index) in navIcons" :key="index" class="flex flex-col items-center" @click="toPage(item.url)">
  190. <image :src="item.image" :style="`width: ${item.size}; height: ${item.size};`" />
  191. <view class="mt-14rpx text-center text-22rpx text-#898989 font-bold">
  192. {{ $t(item.title) }}
  193. </view>
  194. </view>
  195. </view>
  196. <view>
  197. <view class="mb-16rpx text-32rpx">
  198. News
  199. </view>
  200. <scroll-view scroll-x>
  201. <view class="flex items-center gap-22rpx pb-24rpx">
  202. <product v-for="(item, index) in newProducts" :key="index" :item="item" @item-click="toProductDetail" />
  203. </view>
  204. </scroll-view>
  205. </view>
  206. <view>
  207. <wd-tabs v-model="priceTab" :line-width="0" :line-height="0">
  208. <block v-for="item in priceTabList" :key="item">
  209. <wd-tab :title="item.title" />
  210. </block>
  211. </wd-tabs>
  212. <view class="flex flex-wrap gap-22rpx">
  213. <product v-for="(item, index) in newProducts" :key="index" :height="340" :item="item" @item-click="toProductDetail" />
  214. <view />
  215. </view>
  216. </view>
  217. </view>
  218. </z-paging>
  219. </template>
  220. <style>
  221. page {
  222. background: #fff;
  223. }
  224. </style>