mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-ui.git
synced 2026-11-12 20:08:59 +08:00
perf(image): 优化图片加载性能
- 为所有商品图片添加 loading="lazy" 属性实现懒加载 - 为所有图片元素添加 decoding="async" 属性实现异步解码 - 优化购物车页面的商品缩略图加载方式 - 改进订单中心各页面的图片加载策略 - 提升评价系统中图片的加载性能 - 优化会员中心收藏和足迹功能的图片加载 - 改善促销活动页面的图片加载体验 - 更新首页装饰组件中的图片加载属性 - 提高地址管理页面的界面展示效果
This commit is contained in:
@@ -111,6 +111,8 @@
|
||||
goods.goodsSku.thumbnail ||
|
||||
'../assets/images/goodsDetail/item-detail-1.jpg'
|
||||
"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
<div>
|
||||
<p>
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
@click="goGoodsDetail(item.id, item.goodsId)"
|
||||
>
|
||||
<div class="goods-show-img">
|
||||
<img :src="item.thumbnail || item.small" alt=""/>
|
||||
<img :src="item.thumbnail || item.small" loading="lazy" decoding="async" alt=""/>
|
||||
</div>
|
||||
<div class="goods-show-price">
|
||||
<span class="seckill-price text-danger">{{ $filters.unitPrice(item.price, "¥") }}</span>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
<div class="add-info-box-row">
|
||||
<div class="add-info-img">
|
||||
<img :src="detail.thumbnail" alt="">
|
||||
<img :src="detail.thumbnail" loading="lazy" decoding="async" alt="">
|
||||
</div>
|
||||
<div class="add-info-intro">
|
||||
<p>{{detail.goodsName}}</p>
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
<div class="goods-thumb" @click="linkTo(`/goodsDetail?goodsId=${item.goodsId}&skuId=${item.skuId}`)">
|
||||
<img
|
||||
:src="item.goodsImage"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
@error="$event.target.style.visibility = 'hidden'"
|
||||
/>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>投诉商品</td>
|
||||
<td class="hover-color" @click="linkTo(`/goodsDetail?goodsId=${detail.goodsId}&skuId=${detail.skuId}`)"><img :src="detail.goodsImage" width="60" alt=""> {{ detail.goodsName }}</td>
|
||||
<td class="hover-color" @click="linkTo(`/goodsDetail?goodsId=${detail.goodsId}&skuId=${detail.skuId}`)"><img :src="detail.goodsImage" loading="lazy" decoding="async" width="60" alt=""> {{ detail.goodsName }}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>投诉主题</td>
|
||||
@@ -30,7 +30,7 @@
|
||||
<div style="display:flex;align-items:center;">
|
||||
<template v-if="detail.images">
|
||||
<div class="demo-upload-list" v-for="(img, index) in detail.images.split(',')" :key="index">
|
||||
<img :src="img">
|
||||
<img :src="img" loading="lazy" decoding="async">
|
||||
<div class="demo-upload-list-cover">
|
||||
<el-icon @click="handleView(img)"><View /></el-icon>
|
||||
</div>
|
||||
@@ -61,7 +61,7 @@
|
||||
<div style="display:flex;align-items:center;">
|
||||
<template v-if="detail.appealImages">
|
||||
<div class="demo-upload-list" v-for="(img, index) in detail.appealImages.split(',')" :key="index">
|
||||
<img :src="img">
|
||||
<img :src="img" loading="lazy" decoding="async">
|
||||
<div class="demo-upload-list-cover">
|
||||
<el-icon @click="handleView(img)"><View /></el-icon>
|
||||
</div>
|
||||
@@ -124,7 +124,7 @@
|
||||
</table>
|
||||
|
||||
<el-dialog title="图片预览" v-model="visible">
|
||||
<img :src="previewImage" v-if="visible" style="width: 100%">
|
||||
<img :src="previewImage" loading="lazy" decoding="async" v-if="visible" style="width: 100%">
|
||||
</el-dialog>
|
||||
</UserCenterLayout>
|
||||
</div>
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
<div class="goods-thumb" @click="linkTo(`/goodsDetail?goodsId=${item.goodsId}&skuId=${item.skuId}`)">
|
||||
<img
|
||||
:src="item.goodsImage"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
@error="$event.target.style.visibility = 'hidden'"
|
||||
/>
|
||||
@@ -286,3 +288,7 @@ export default {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
<div class="fav-thumb" @click="openItem(item)">
|
||||
<img
|
||||
:src="params.type === 'GOODS' ? item.image : item.storeLogo"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
@error="$event.target.style.visibility = 'hidden'"
|
||||
/>
|
||||
@@ -55,6 +57,8 @@
|
||||
<div class="fav-thumb" @click="openItem(item)">
|
||||
<img
|
||||
:src="params.type === 'GOODS' ? item.image : item.storeLogo"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
@error="$event.target.style.visibility = 'hidden'"
|
||||
/>
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
<ul class="goods-eval">
|
||||
<li >
|
||||
<div class="goods-con">
|
||||
<img :src="orderGoods.image" class="hover-pointer" alt="" width="100" @click="goGoodsDetail(orderGoods.skuId, orderGoods.goodsId)">
|
||||
<img :src="orderGoods.image" loading="lazy" decoding="async" class="hover-pointer" alt="" width="100" @click="goGoodsDetail(orderGoods.skuId, orderGoods.goodsId)">
|
||||
<p class="hover-pointer color999" @click="goGoodsDetail(orderGoods.skuId, orderGoods.goodsId)">{{orderGoods.goodsName}}</p>
|
||||
<p>{{ $filters.unitPrice(orderGoods.goodsPrice, '¥') }}</p>
|
||||
</div>
|
||||
@@ -40,7 +40,7 @@
|
||||
<div class="upload-section">
|
||||
<div class="upload-row">
|
||||
<div class="demo-upload-list" v-for="(img, index) in orderGoods.uploadList" :key="index">
|
||||
<img :src="img">
|
||||
<img :src="img" loading="lazy" decoding="async">
|
||||
<div class="demo-upload-list-cover">
|
||||
<el-icon @click="handleView(img)"><View /></el-icon>
|
||||
<el-icon @click="handleRemove(index)"><Delete /></el-icon>
|
||||
@@ -69,7 +69,7 @@
|
||||
<el-button type="primary" :loading="loading" @click="save">发表</el-button>
|
||||
</div>
|
||||
<el-dialog title="图片预览" v-model="visible">
|
||||
<img :src="previewImage" v-if="visible" style="width: 100%">
|
||||
<img :src="previewImage" loading="lazy" decoding="async" v-if="visible" style="width: 100%">
|
||||
</el-dialog>
|
||||
</UserCenterLayout>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<div class="goods-row" v-if="orderGoods.goodsName">
|
||||
<img
|
||||
:src="orderGoods.goodsImage"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
@click="goGoodsDetail(orderGoods.skuId, orderGoods.goodsId)"
|
||||
@error="$event.target.style.visibility = 'hidden'"
|
||||
@@ -47,6 +49,8 @@
|
||||
v-for="(img, index) in orderGoods.images.split(',')"
|
||||
:key="index"
|
||||
:src="img"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
@click="handleView(img)"
|
||||
/>
|
||||
@@ -61,6 +65,8 @@
|
||||
v-for="(img, index) in orderGoods.replyImage.split(',')"
|
||||
:key="index"
|
||||
:src="img"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
@click="handleView(img)"
|
||||
/>
|
||||
@@ -68,7 +74,7 @@
|
||||
</div>
|
||||
|
||||
<el-dialog title="查看图片" v-model="visible" width="640px">
|
||||
<img :src="previewImage" v-if="visible" class="preview-img" alt="" />
|
||||
<img :src="previewImage" loading="lazy" decoding="async" v-if="visible" class="preview-img" alt="" />
|
||||
</el-dialog>
|
||||
</UserCenterLayout>
|
||||
</div>
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
@click="goodsDetail(order.skuId, order.goodsId)"
|
||||
class="hover-color"
|
||||
:src="order.goodsImage"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
@error="$event.target.style.visibility = 'hidden'"
|
||||
/>
|
||||
@@ -89,7 +91,7 @@
|
||||
<div>
|
||||
<div class="goods-list modal-goods">
|
||||
<img @click="goodsDetail(singleOrder.skuId, singleOrder.goodsId)" class="hover-color"
|
||||
:src="singleOrder.goodsImage" alt=""/>
|
||||
:src="singleOrder.goodsImage" loading="lazy" decoding="async" alt=""/>
|
||||
<div>
|
||||
<div class="hover-color" @click="goodsDetail(singleOrder.skuId, singleOrder.goodsId)">
|
||||
{{ singleOrder.goodsName }}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="goods-row">
|
||||
<img :src="afterSale.goodsImage" alt="" @error="$event.target.style.visibility = 'hidden'">
|
||||
<img :src="afterSale.goodsImage" loading="lazy" decoding="async" alt="" @error="$event.target.style.visibility = 'hidden'">
|
||||
<div class="goods-info">
|
||||
<div class="goods-name">{{ afterSale.goodsName }}</div>
|
||||
<div class="store-line">
|
||||
@@ -93,6 +93,8 @@
|
||||
v-for="img in afterSale.afterSaleImage.split(',')"
|
||||
:key="img"
|
||||
:src="img"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
@click="perviewImg(img)"
|
||||
class="hover-pointer"
|
||||
alt=""
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<el-table-column label="商品名称">
|
||||
<template #default="{ row }">
|
||||
<div style="padding:5px;display:flex;">
|
||||
<img :src="row.image" style="vertical-align: top;" width="60" height="60" alt="">
|
||||
<img :src="row.image" loading="lazy" decoding="async" style="vertical-align: top;" width="60" height="60" alt="">
|
||||
<span class="ml_10">{{ row.goodsName }}</span>
|
||||
</div>
|
||||
</template>
|
||||
@@ -50,7 +50,7 @@
|
||||
<div class="upload-section">
|
||||
<div class="upload-row">
|
||||
<div class="demo-upload-list" v-for="(img, index) in uploadList" :key="index">
|
||||
<img :src="img">
|
||||
<img :src="img" loading="lazy" decoding="async">
|
||||
<div class="demo-upload-list-cover">
|
||||
<el-icon @click="handleView(img)"><View /></el-icon>
|
||||
<el-icon @click="handleRemove(index)"><Delete /></el-icon>
|
||||
@@ -95,7 +95,7 @@
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<el-dialog title="图片预览" v-model="visible">
|
||||
<img :src="previewImage" v-if="visible" style="width: 100%">
|
||||
<img :src="previewImage" loading="lazy" decoding="async" v-if="visible" style="width: 100%">
|
||||
</el-dialog>
|
||||
</div>
|
||||
</UserCenterLayout>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</div>
|
||||
<div class="goods-eval">
|
||||
<div class="goods-con">
|
||||
<img :src="orderGoods.image" class="hover-pointer" alt="" width="100" @click="goGoodsDetail(orderGoods.skuId, orderGoods.goodsId)">
|
||||
<img :src="orderGoods.image" loading="lazy" decoding="async" class="hover-pointer" alt="" width="100" @click="goGoodsDetail(orderGoods.skuId, orderGoods.goodsId)">
|
||||
<p class="hover-pointer color999" @click="goGoodsDetail(orderGoods.skuId, orderGoods.goodsId)">{{orderGoods.goodsName}}</p>
|
||||
<p>{{ $filters.unitPrice(orderGoods.goodsPrice, '¥') }}</p>
|
||||
</div>
|
||||
@@ -28,7 +28,7 @@
|
||||
<div class="upload-section">
|
||||
<div class="upload-row">
|
||||
<div class="demo-upload-list" v-for="(img, index) in orderGoods.uploadList" :key="index">
|
||||
<img :src="img">
|
||||
<img :src="img" loading="lazy" decoding="async">
|
||||
<div class="demo-upload-list-cover">
|
||||
<el-icon @click="handleView(img)"><View /></el-icon>
|
||||
<el-icon @click="handleRemove(index)"><Delete /></el-icon>
|
||||
@@ -56,7 +56,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<el-dialog title="图片预览" v-model="visible">
|
||||
<img :src="previewImage" v-if="visible" style="width: 100%">
|
||||
<img :src="previewImage" loading="lazy" decoding="async" v-if="visible" style="width: 100%">
|
||||
</el-dialog>
|
||||
</UserCenterLayout>
|
||||
</div>
|
||||
|
||||
@@ -4,33 +4,33 @@
|
||||
<template #extra>
|
||||
<el-button type="primary" @click="add">添加新地址</el-button>
|
||||
</template>
|
||||
<div class="address-box" v-for="(item, index) in list" :key="index">
|
||||
<div class="address-header">
|
||||
<span>
|
||||
{{ item.name }}
|
||||
<el-tag class="ml_10 default-address-tag" v-if="item.isDefault">默认地址</el-tag>
|
||||
<el-tag class="ml_10" v-if="item.alias" color="warning">{{item.alias}}</el-tag>
|
||||
</span>
|
||||
<div class="address-action">
|
||||
<span @click="edit(item.id)"><el-icon><Edit /></el-icon>修改</span>
|
||||
<span @click="del(item.id)"><el-icon><Delete /></el-icon>删除</span>
|
||||
<div class="address-list" v-if="list.length">
|
||||
<div class="address-box" v-for="(item, index) in list" :key="index">
|
||||
<div class="address-header">
|
||||
<div class="address-title">
|
||||
<span class="address-name">{{ item.name }}</span>
|
||||
<span class="address-mobile">{{ item.mobile }}</span>
|
||||
<el-tag size="small" class="default-address-tag" v-if="item.isDefault">默认地址</el-tag>
|
||||
<el-tag size="small" class="alias-tag" v-if="item.alias">{{item.alias}}</el-tag>
|
||||
</div>
|
||||
<div class="address-action">
|
||||
<span @click="edit(item.id)"><el-icon><Edit /></el-icon>修改</span>
|
||||
<span class="del-btn" @click="del(item.id)"><el-icon><Delete /></el-icon>删除</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="address-content">
|
||||
<p>
|
||||
<span class="address-content-title">收货地区</span>
|
||||
<span>{{ $filters.unitAddress(item.consigneeAddressPath) }}</span>
|
||||
</p>
|
||||
<p>
|
||||
<span class="address-content-title">详细地址</span>
|
||||
<span>{{ item.detail }}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="address-content">
|
||||
<p>
|
||||
<span class="address-content-title"> 收 货 人 :</span> {{ item.name }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="address-content-title">收货地区:</span>{{ $filters.unitAddress(item.consigneeAddressPath) }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="address-content-title">详细地址:</span> {{ item.detail }}
|
||||
</p>
|
||||
<p>
|
||||
<span class="address-content-title">手机号码:</span> {{ item.mobile }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<el-empty v-else description="暂无收货地址" />
|
||||
</UserCenterLayout>
|
||||
</div>
|
||||
</template>
|
||||
@@ -95,63 +95,110 @@ export default {
|
||||
.wrapper {
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.address-box {
|
||||
padding: 15px;
|
||||
margin: 0;
|
||||
border-bottom: 1px solid $border_color;
|
||||
margin-bottom: 16px;
|
||||
padding: 18px 20px;
|
||||
border: 1px solid #ebedf0;
|
||||
border-radius: 8px;
|
||||
background: #fff;
|
||||
transition: box-shadow 0.2s ease, border-color 0.2s ease;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border-color: #dcdfe6;
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.06);
|
||||
}
|
||||
}
|
||||
|
||||
.address-header {
|
||||
cursor: pointer;
|
||||
height: 35px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
@include title_color($light_title_color);
|
||||
font-size: 18px;
|
||||
padding-bottom: 12px;
|
||||
border-bottom: 1px dashed #ebedf0;
|
||||
}
|
||||
|
||||
.address-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.address-name {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: $light_title_color;
|
||||
}
|
||||
|
||||
.address-mobile {
|
||||
margin-left: 14px;
|
||||
font-size: 14px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.address-content {
|
||||
cursor: pointer;
|
||||
padding-top: 6px;
|
||||
font-size: 14px;
|
||||
color: #606266;
|
||||
|
||||
> p {
|
||||
padding: 12px 0;
|
||||
display: flex;
|
||||
padding: 6px 0;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.address-content-title {
|
||||
|
||||
flex-shrink: 0;
|
||||
width: 70px;
|
||||
color: #909399;
|
||||
}
|
||||
|
||||
.address-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15px;
|
||||
flex-shrink: 0;
|
||||
gap: 16px;
|
||||
margin-left: 16px;
|
||||
|
||||
span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
font-size: 14px;
|
||||
color: $theme_color;
|
||||
font-size: 13px;
|
||||
color: #909399;
|
||||
cursor: pointer;
|
||||
transition: color 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
color: $theme_color;
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.del-btn:hover {
|
||||
color: #f56c6c;
|
||||
}
|
||||
}
|
||||
|
||||
.default-address-tag {
|
||||
margin-left: 10px;
|
||||
background-color: #fff3f2 !important;
|
||||
border: 1px solid $theme_color !important;
|
||||
color: $theme_color !important;
|
||||
}
|
||||
|
||||
.alias-tag {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#map-container {
|
||||
width: 500px;
|
||||
height: 300px;
|
||||
|
||||
@@ -54,6 +54,8 @@
|
||||
@click="goodsDetail(goods.skuId, goods.goodsId)"
|
||||
class="hover-color"
|
||||
:src="goods.image"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
@error="$event.target.style.visibility = 'hidden'"
|
||||
/>
|
||||
@@ -132,6 +134,8 @@
|
||||
@click="goodsDetail(goods.skuId, goods.goodsId)"
|
||||
class="hover-color"
|
||||
:src="goods.image"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
@error="$event.target.style.visibility = 'hidden'"
|
||||
/>
|
||||
|
||||
@@ -216,6 +216,8 @@
|
||||
<img
|
||||
@click="goodsDetail(goods.skuId, goods.goodsId)"
|
||||
:src="goods.image"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
alt=""
|
||||
/>
|
||||
<p
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
@click="goodsDetail(item.id, item.goodsId)"
|
||||
>
|
||||
<div class="thumb">
|
||||
<img :src="item.thumbnail" :alt="item.goodsName" />
|
||||
<img :src="item.thumbnail" loading="lazy" decoding="async" :alt="item.goodsName" />
|
||||
</div>
|
||||
<p class="goods-name">{{ item.goodsName }}</p>
|
||||
<p class="goods-price">{{ $filters.unitPrice(item.price, "¥") }}</p>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
@click="goGoodsDetail(item.id)"
|
||||
>
|
||||
<div class="goods-show-img">
|
||||
<img :src="itemThumbnail(item)" />
|
||||
<img :src="itemThumbnail(item)" loading="lazy" decoding="async" />
|
||||
</div>
|
||||
<div class="goods-show-price">
|
||||
<span>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<div v-else class="goods-show-info1" v-for="(item, index) in goodsList" :key="index"
|
||||
@click="goGoodsDetail(item.skuId, item.goodsId)">
|
||||
<div class="goods-show-img">
|
||||
<img :src="item.goodsImage" :alt="item.goodsName" />
|
||||
<img :src="item.goodsImage" loading="lazy" decoding="async" :alt="item.goodsName" />
|
||||
</div>
|
||||
<div class="goods-show-price">
|
||||
<span class="seckill-price text-danger">{{ $filters.unitPrice(item.price, "¥") }}</span>
|
||||
|
||||
Reference in New Issue
Block a user