添加首页加载skeleton
This commit is contained in:
@@ -100,9 +100,11 @@
|
||||
@click="emit('select-product', product)"
|
||||
>
|
||||
<view class="hmall-product-image-wrapper hmall-product-image-wrapper-fixed">
|
||||
<view class="hmall-product-image-placeholder"></view>
|
||||
<image
|
||||
class="hmall-product-image"
|
||||
:class="['hmall-product-image', isProductImageLoaded(product.id) ? 'hmall-product-image-loaded' : '']"
|
||||
:src="getProductCover(product)"
|
||||
@load="() => handleProductImageLoad(product.id)"
|
||||
@error="() => handleProductImageError(product.id)"
|
||||
mode="aspectFill"
|
||||
/>
|
||||
@@ -137,11 +139,11 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else-if="loading" class="hmall-loading-state">
|
||||
<view v-else-if="pageLoading || loading" class="hmall-loading-state">
|
||||
<text class="hmall-loading-text">正在加载商品...</text>
|
||||
</view>
|
||||
|
||||
<view v-else class="hmall-empty-wrap">
|
||||
<view v-else-if="!pageLoading" class="hmall-empty-wrap">
|
||||
<view v-if="emptyStateDescription != ''" class="hmall-empty-state-extended">
|
||||
<EmptyState :text="emptyStateTitle"></EmptyState>
|
||||
<text class="hmall-empty-desc">{{ emptyStateDescription }}</text>
|
||||
@@ -168,6 +170,7 @@ import type { MarketingChannel, ChannelProduct, SimpleCategoryChannel } from '@/
|
||||
|
||||
const failedProductImageIds = ref<string[]>([])
|
||||
const failedChannelImageIds = ref<string[]>([])
|
||||
const loadedProductImageIds = ref<string[]>([])
|
||||
|
||||
type SecondaryCategoryPage = {
|
||||
id: string
|
||||
@@ -199,6 +202,10 @@ const props = defineProps({
|
||||
type: Array<Product>,
|
||||
default: [] as Array<Product>
|
||||
},
|
||||
pageLoading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
@@ -339,11 +346,28 @@ function handleProductImageError(productId: string): void {
|
||||
if (productId == '') {
|
||||
return
|
||||
}
|
||||
handleProductImageLoad(productId)
|
||||
if (failedProductImageIds.value.indexOf(productId) == -1) {
|
||||
failedProductImageIds.value.push(productId)
|
||||
}
|
||||
}
|
||||
|
||||
function handleProductImageLoad(productId: string): void {
|
||||
if (productId == '') {
|
||||
return
|
||||
}
|
||||
if (loadedProductImageIds.value.indexOf(productId) == -1) {
|
||||
loadedProductImageIds.value.push(productId)
|
||||
}
|
||||
}
|
||||
|
||||
function isProductImageLoaded(productId: string): boolean {
|
||||
if (productId == '') {
|
||||
return false
|
||||
}
|
||||
return loadedProductImageIds.value.indexOf(productId) != -1
|
||||
}
|
||||
|
||||
function getProductTitle(product: Product): string {
|
||||
if (product.short_title != null && product.short_title != '') {
|
||||
return product.short_title
|
||||
@@ -777,6 +801,17 @@ function showMarketPrice(product: Product): boolean {
|
||||
background: #f2f2f2;
|
||||
}
|
||||
|
||||
.hmall-product-image-placeholder {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: linear-gradient(90deg, #edf0f4 0%, #f9fbfd 48%, #edf0f4 100%);
|
||||
background-size: 220% 100%;
|
||||
animation: hmall-image-shimmer 1.35s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.hmall-product-image {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -784,6 +819,12 @@ function showMarketPrice(product: Product): boolean {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 18rpx 18rpx 0 0;
|
||||
opacity: 0;
|
||||
transition: opacity 220ms ease;
|
||||
}
|
||||
|
||||
.hmall-product-image-loaded {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.hmall-product-image-wrapper-fixed {
|
||||
@@ -795,6 +836,15 @@ function showMarketPrice(product: Product): boolean {
|
||||
background: #ffffff;
|
||||
}
|
||||
|
||||
@keyframes hmall-image-shimmer {
|
||||
0% {
|
||||
background-position: 200% 0;
|
||||
}
|
||||
100% {
|
||||
background-position: -20% 0;
|
||||
}
|
||||
}
|
||||
|
||||
.hmall-product-body {
|
||||
padding: 14rpx 14rpx 16rpx;
|
||||
background: #ffffff;
|
||||
|
||||
@@ -4,12 +4,10 @@
|
||||
<view
|
||||
v-for="item in modules"
|
||||
:key="item.key"
|
||||
class="jd2-module-item"
|
||||
:class="isServiceModule ? 'jd2-module-item-service' : ''"
|
||||
:class="['jd2-module-item', activeModule == item.key ? 'jd2-module-item-active' : '', isServiceModule ? 'jd2-module-item-service' : '']"
|
||||
@click="emit('change-module', item.key)"
|
||||
>
|
||||
<text :class="['jd2-module-text', activeModule == item.key ? 'jd2-module-text-active' : '', isServiceModule ? 'jd2-module-text-service' : '']">{{ item.label }}</text>
|
||||
<view v-if="activeModule == item.key" :class="['jd2-module-line', isServiceModule ? 'jd2-module-line-service' : '']"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
@@ -121,17 +119,27 @@ function handleSearch() {
|
||||
padding-right: 24rpx;
|
||||
height: 62rpx;
|
||||
box-sizing: border-box;
|
||||
padding-top: 6rpx;
|
||||
}
|
||||
|
||||
.jd2-module-item {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 62rpx;
|
||||
margin-right: 36rpx;
|
||||
min-width: 132rpx;
|
||||
height: 56rpx;
|
||||
margin-right: 20rpx;
|
||||
padding-left: 24rpx;
|
||||
padding-right: 24rpx;
|
||||
border-radius: 999rpx;
|
||||
background-color: #eceff3;
|
||||
border-width: 2rpx;
|
||||
border-style: solid;
|
||||
border-color: transparent;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.jd2-module-item-service {
|
||||
margin-right: 28rpx;
|
||||
margin-right: 20rpx;
|
||||
}
|
||||
|
||||
.jd2-module-text {
|
||||
@@ -155,16 +163,18 @@ function handleSearch() {
|
||||
color: #0f766e;
|
||||
}
|
||||
|
||||
.jd2-module-item-active {
|
||||
border-color: rgba(215, 39, 39, 0.16);
|
||||
background-color: #fef2f2;
|
||||
box-shadow: 0 10rpx 22rpx rgba(215, 39, 39, 0.08);
|
||||
}
|
||||
|
||||
.jd2-module-line {
|
||||
margin-top: 8rpx;
|
||||
width: 32rpx;
|
||||
height: 6rpx;
|
||||
border-radius: 999rpx;
|
||||
background: #e2231a;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jd2-module-line-service {
|
||||
background: #16a085;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jd2-search-wrap {
|
||||
|
||||
Reference in New Issue
Block a user