|
@@ -127,22 +127,29 @@ const priceTabList = ref([
|
|
|
])
|
|
|
|
|
|
const dataList = ref<any>([])
|
|
|
+const isProductListLoading = ref(false) // 商品列表加载状态
|
|
|
+
|
|
|
async function queryList(pageNo: number, pageSize: number) {
|
|
|
- // 获取当前选中tab的价格范围,默认为第一个tab (0-300)
|
|
|
- // const currentTab = priceTabList.value[priceTab.value] || priceTabList.value[0]
|
|
|
- // const minPrice = currentTab?.minPrice ?? 0
|
|
|
- // const maxPrice = currentTab?.maxPrice ?? 300
|
|
|
+ // 如果是第一页,显示骨架屏
|
|
|
+ if (pageNo === 1) {
|
|
|
+ isProductListLoading.value = true
|
|
|
+ }
|
|
|
|
|
|
- const params = {
|
|
|
- page: pageNo,
|
|
|
- size: pageSize,
|
|
|
- sort: 'SALES_DESC',
|
|
|
- price: priceTab.value,
|
|
|
- // minPrice,
|
|
|
- // maxPrice,
|
|
|
+ try {
|
|
|
+ const params = {
|
|
|
+ page: pageNo,
|
|
|
+ size: pageSize,
|
|
|
+ sort: 'SALES_DESC',
|
|
|
+ price: priceTab.value,
|
|
|
+ }
|
|
|
+ const res = await getList(params)
|
|
|
+ paging.value.complete(res.data.list)
|
|
|
+ }
|
|
|
+ finally {
|
|
|
+ if (pageNo === 1) {
|
|
|
+ isProductListLoading.value = false
|
|
|
+ }
|
|
|
}
|
|
|
- const res = await getList(params)
|
|
|
- paging.value.complete(res.data.list)
|
|
|
}
|
|
|
|
|
|
async function getBannerList() {
|
|
@@ -151,6 +158,8 @@ async function getBannerList() {
|
|
|
}
|
|
|
|
|
|
const unread = ref(0)
|
|
|
+const isPageLoading = ref(true) // 页面加载状态
|
|
|
+
|
|
|
async function getUnread() {
|
|
|
try {
|
|
|
const res = await noticeUnread()
|
|
@@ -161,10 +170,18 @@ async function getUnread() {
|
|
|
catch {}
|
|
|
}
|
|
|
|
|
|
-onShow(() => {
|
|
|
- getUnread()
|
|
|
- getNewList()
|
|
|
- getBannerList()
|
|
|
+onShow(async () => {
|
|
|
+ try {
|
|
|
+ isPageLoading.value = true
|
|
|
+ await Promise.all([
|
|
|
+ getUnread(),
|
|
|
+ getNewList(),
|
|
|
+ getBannerList(),
|
|
|
+ ])
|
|
|
+ }
|
|
|
+ finally {
|
|
|
+ isPageLoading.value = false
|
|
|
+ }
|
|
|
})
|
|
|
</script>
|
|
|
|
|
@@ -194,63 +211,166 @@ onShow(() => {
|
|
|
</view>
|
|
|
</view>
|
|
|
</template>
|
|
|
- <wd-swiper
|
|
|
- v-model:current="current"
|
|
|
- :list="swiperList"
|
|
|
- value-key="image"
|
|
|
- autoplay
|
|
|
- :indicator="{ type: 'fraction' }"
|
|
|
- indicator-position="bottom-right"
|
|
|
- @click="handleSwiperClick"
|
|
|
- />
|
|
|
- <view class="px-24rpx pb-24rpx">
|
|
|
- <view class="flex items-end justify-between pb-22rpx pt-24rpx">
|
|
|
- <view
|
|
|
- v-for="(item, index) in navIcons"
|
|
|
- :key="index"
|
|
|
- class="flex flex-col items-center"
|
|
|
- @click="toPage(item.url)"
|
|
|
- >
|
|
|
- <image :src="item.image" :style="`width: ${item.size}; height: ${item.size};`" />
|
|
|
- <view class="mt-14rpx whitespace-pre-line text-center text-22rpx text-#898989 font-bold">
|
|
|
- {{ $t(item.title) }}
|
|
|
- </view>
|
|
|
+ <!-- 页面加载时显示骨架屏 -->
|
|
|
+ <template v-if="isPageLoading">
|
|
|
+ <!-- 轮播图骨架屏 -->
|
|
|
+ <wd-skeleton
|
|
|
+ :row-col="[{ height: '400rpx' }]"
|
|
|
+ animation="gradient"
|
|
|
+ />
|
|
|
+
|
|
|
+ <view class="px-24rpx pb-24rpx">
|
|
|
+ <!-- 导航图标区域骨架屏 -->
|
|
|
+ <view class="pb-22rpx pt-24rpx">
|
|
|
+ <wd-skeleton
|
|
|
+ :row-col="[
|
|
|
+ [
|
|
|
+ { width: '100rpx', height: '100rpx', type: 'circle' },
|
|
|
+ { width: '100rpx', height: '100rpx', type: 'circle' },
|
|
|
+ { width: '100rpx', height: '100rpx', type: 'circle' },
|
|
|
+ { width: '100rpx', height: '100rpx', type: 'circle' },
|
|
|
+ { width: '100rpx', height: '100rpx', type: 'circle' },
|
|
|
+ ],
|
|
|
+ [
|
|
|
+ { width: '60rpx', height: '24rpx' },
|
|
|
+ { width: '60rpx', height: '24rpx' },
|
|
|
+ { width: '60rpx', height: '24rpx' },
|
|
|
+ { width: '60rpx', height: '24rpx' },
|
|
|
+ { width: '60rpx', height: '24rpx' },
|
|
|
+ ],
|
|
|
+ ]"
|
|
|
+ animation="gradient"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 新品区域骨架屏 -->
|
|
|
+ <view class="mb-32rpx">
|
|
|
+ <wd-skeleton
|
|
|
+ :row-col="[
|
|
|
+ { width: '120rpx', height: '32rpx', marginBottom: '16rpx' }, // 标题
|
|
|
+ [
|
|
|
+ { width: '260rpx', height: '260rpx' },
|
|
|
+ { width: '260rpx', height: '260rpx', marginLeft: '16rpx' },
|
|
|
+ { width: '260rpx', height: '260rpx', marginLeft: '16rpx' },
|
|
|
+ ],
|
|
|
+ ]"
|
|
|
+ animation="gradient"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 价格分类标签骨架屏 -->
|
|
|
+ <view class="mb-20rpx">
|
|
|
+ <wd-skeleton
|
|
|
+ :row-col="[
|
|
|
+ [
|
|
|
+ { width: '80rpx', height: '36rpx' },
|
|
|
+ { width: '80rpx', height: '36rpx', marginLeft: '20rpx' },
|
|
|
+ { width: '80rpx', height: '36rpx', marginLeft: '20rpx' },
|
|
|
+ { width: '80rpx', height: '36rpx', marginLeft: '20rpx' },
|
|
|
+ { width: '80rpx', height: '36rpx', marginLeft: '20rpx' },
|
|
|
+ ],
|
|
|
+ ]"
|
|
|
+ animation="gradient"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 商品列表骨架屏 -->
|
|
|
+ <view class="grid grid-cols-2 gap-20rpx">
|
|
|
+ <wd-skeleton
|
|
|
+ v-for="i in 6"
|
|
|
+ :key="i"
|
|
|
+ :row-col="[
|
|
|
+ { height: '340rpx' }, // 商品图片
|
|
|
+ { width: '180rpx', height: '40rpx', marginTop: '10rpx' }, // 商品名称
|
|
|
+ [
|
|
|
+ { width: '80rpx', height: '24rpx' }, // 价格
|
|
|
+ { width: '60rpx', height: '20rpx' }, // 销量
|
|
|
+ ],
|
|
|
+ ]"
|
|
|
+ animation="gradient"
|
|
|
+ />
|
|
|
</view>
|
|
|
</view>
|
|
|
- <view v-if="newProducts.length">
|
|
|
- <view class="mb-16rpx text-32rpx">
|
|
|
- {{ $t('home.news') }}
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <!-- 实际内容 -->
|
|
|
+ <template v-else>
|
|
|
+ <wd-swiper
|
|
|
+ v-model:current="current"
|
|
|
+ :list="swiperList"
|
|
|
+ value-key="image"
|
|
|
+ autoplay
|
|
|
+ indicator
|
|
|
+ indicator-position="bottom-right"
|
|
|
+ @click="handleSwiperClick"
|
|
|
+ />
|
|
|
+ <view class="px-24rpx pb-24rpx">
|
|
|
+ <view class="flex items-end justify-between pb-22rpx pt-24rpx">
|
|
|
+ <view
|
|
|
+ v-for="(item, index) in navIcons"
|
|
|
+ :key="index"
|
|
|
+ class="flex flex-col items-center"
|
|
|
+ @click="toPage(item.url)"
|
|
|
+ >
|
|
|
+ <image :src="item.image" :style="`width: ${item.size}; height: ${item.size};`" />
|
|
|
+ <view class="mt-14rpx whitespace-pre-line text-center text-22rpx text-#898989 font-bold">
|
|
|
+ {{ $t(item.title) }}
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
- <scroll-view scroll-x>
|
|
|
- <view class="flex items-center gap-16rpx">
|
|
|
+ <view v-if="newProducts.length">
|
|
|
+ <view class="mb-16rpx text-32rpx">
|
|
|
+ {{ $t('home.news') }}
|
|
|
+ </view>
|
|
|
+ <scroll-view scroll-x class="whitespace-nowrap">
|
|
|
+ <view class="flex items-center gap-16rpx pb-20rpx" style="min-width: max-content;">
|
|
|
+ <Product
|
|
|
+ v-for="(item, index) in newProducts"
|
|
|
+ :key="index"
|
|
|
+ :title-font-size="18"
|
|
|
+ :item="item"
|
|
|
+ class="shrink-0"
|
|
|
+ @item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId })"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+ </scroll-view>
|
|
|
+ </view>
|
|
|
+ <view class="productList">
|
|
|
+ <wd-tabs v-model="priceTab" slidable="always" :line-width="0" :line-height="0" @click="() => queryList(1, 20)">
|
|
|
+ <template v-for="item in priceTabList" :key="item">
|
|
|
+ <wd-tab :title="$t(item.title)" :name="item.value" />
|
|
|
+ </template>
|
|
|
+ </wd-tabs>
|
|
|
+ <!-- Tab切换时的商品列表骨架屏 -->
|
|
|
+ <view v-if="isProductListLoading" class="grid grid-cols-2 gap-20rpx">
|
|
|
+ <wd-skeleton
|
|
|
+ v-for="i in 6"
|
|
|
+ :key="i"
|
|
|
+ :row-col="[
|
|
|
+ { height: '340rpx', borderRadius: '12rpx' }, // 商品图片
|
|
|
+ { width: '180rpx', height: '40rpx', marginTop: '10rpx' }, // 商品名称
|
|
|
+ [
|
|
|
+ { width: '80rpx', height: '24rpx' }, // 价格
|
|
|
+ { width: '60rpx', height: '20rpx' }, // 销量
|
|
|
+ ],
|
|
|
+ ]"
|
|
|
+ animation="gradient"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
+ <!-- 实际商品列表 -->
|
|
|
+ <view v-else class="grid grid-cols-2 gap-20rpx">
|
|
|
<Product
|
|
|
- v-for="(item, index) in newProducts"
|
|
|
+ v-for="(item, index) in dataList"
|
|
|
:key="index"
|
|
|
- :title-font-size="18"
|
|
|
+ width="100%"
|
|
|
+ :height="340"
|
|
|
:item="item"
|
|
|
@item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId })"
|
|
|
/>
|
|
|
</view>
|
|
|
- </scroll-view>
|
|
|
- </view>
|
|
|
- <view class="productList">
|
|
|
- <wd-tabs v-model="priceTab" slidable="always" :line-width="0" :line-height="0" @click="() => queryList(1, 20)">
|
|
|
- <template v-for="item in priceTabList" :key="item">
|
|
|
- <wd-tab :title="$t(item.title)" :name="item.value" />
|
|
|
- </template>
|
|
|
- </wd-tabs>
|
|
|
- <view class="grid grid-cols-2 gap-20rpx">
|
|
|
- <Product
|
|
|
- v-for="(item, index) in dataList"
|
|
|
- :key="index"
|
|
|
- width="100%"
|
|
|
- :height="340"
|
|
|
- :item="item"
|
|
|
- @item-click="toPage('/pages/productDetail/productDetail', { productId: item.productId })"
|
|
|
- />
|
|
|
</view>
|
|
|
</view>
|
|
|
- </view>
|
|
|
+ </template>
|
|
|
</z-paging>
|
|
|
</template>
|
|
|
|