perf(image): 优化图片加载性能

- 为所有商品图片添加 loading="lazy" 属性实现懒加载
- 为所有图片元素添加 decoding="async" 属性实现异步解码
- 优化购物车页面的商品缩略图加载方式
- 改进订单中心各页面的图片加载策略
- 提升评价系统中图片的加载性能
- 优化会员中心收藏和足迹功能的图片加载
- 改善促销活动页面的图片加载体验
- 更新首页装饰组件中的图片加载属性
- 提高地址管理页面的界面展示效果
This commit is contained in:
pikachu1995@126.com
2026-10-08 14:36:22 +08:00
parent 4c232284f8
commit 1b275cf592
34 changed files with 333 additions and 92 deletions

View File

@@ -4,7 +4,7 @@
<ul>
<li v-for="(goods,goodsIndex) in cartList" :key="goodsIndex">
<div>
<img :src="goods.goodsSku.thumbnail" width="90" height="90" alt="">
<img :src="goods.goodsSku.thumbnail" loading="lazy" decoding="async" width="90" height="90" alt="">
</div>
<div>
<p class="hover-color" @click="linkTo(`/goodsDetail?skuId=${goods.goodsSku.id}&goodsId=${goods.goodsSku.goodsId}`)">{{goods.goodsSku.goodsName}}</p>
@@ -21,7 +21,7 @@
<li v-for="(order,orderIndex) in orderList" :key="orderIndex">
<div class="order-status"><span>{{filterOrderStatus(order.orderStatus)}}</span><span>{{order.createTime}}</span></div>
<div class="goods-img">
<img :src="img.image"
<img :src="img.image" loading="lazy" decoding="async"
@click="linkTo(`/goodsDetail?skuId=${img.skuId}&goodsId=${img.goodsId}`)"
v-for="(img,imgIndex) in order.orderItems"
:key="imgIndex" width="40" height="40" alt="">
@@ -54,7 +54,7 @@
<div v-else-if="title === '我的足迹'" class="tracks-con">
<ul>
<li v-for="(track,trackIndex) in tracksList" :key="trackIndex">
<img :src="track.thumbnail" :alt="track.thumbnail" @click="linkTo(`/goodsDetail?skuId=${track.id}&goodsId=${track.goodsId}`)" width="100" height="100">
<img :src="track.thumbnail" loading="lazy" decoding="async" :alt="track.thumbnail" @click="linkTo(`/goodsDetail?skuId=${track.id}&goodsId=${track.goodsId}`)" width="100" height="100">
<div @click="addToCart(track.id)">加入购物车</div>
<p class="global_color">{{ $filters.unitPrice(track.price, '¥') }}</p>
</li>
@@ -64,7 +64,7 @@
<div v-else-if="title === '我的收藏'" class="collect-con">
<ul>
<li v-for="(collect,collectIndex) in collectList" :key="collectIndex">
<img :src="collect.image" :alt="collect.image" @click="linkTo(`/goodsDetail?skuId=${collect.skuId}&goodsId=${collect.goodsId}`)" width="100" height="100">
<img :src="collect.image" loading="lazy" decoding="async" :alt="collect.image" @click="linkTo(`/goodsDetail?skuId=${collect.skuId}&goodsId=${collect.goodsId}`)" width="100" height="100">
<div @click="addToCart(collect.skuId)">加入购物车</div>
<span class="del-icon" @click.stop="cancelCollect(collect.skuId)">
<el-icon><Delete /></el-icon>

View File

@@ -62,7 +62,7 @@
:class="{ borderColor: img === item.previewImg }"
:key="imgIndex"
>
<img :src="img" alt="">
<img :src="img" loading="lazy" decoding="async" alt="">
</div>
</div>
@@ -71,7 +71,7 @@
<span @click.stop="rotatePreviewImg(0, item)"><el-icon><Refresh /></el-icon>左转</span>
<span @click.stop="rotatePreviewImg(1, item)"><el-icon><Refresh /></el-icon>右转</span>
</div>
<img :src="item.previewImg" :style="{ transform: `rotate(${item.deg || 0}deg)` }" width="198" alt="">
<img :src="item.previewImg" loading="lazy" decoding="async" :style="{ transform: `rotate(${item.deg || 0}deg)` }" width="198" alt="">
</div>
<p class="remarks-sub">
<span class="remarks-item">{{ item.goodsName }}</span>
@@ -88,7 +88,7 @@
:class="{ borderColor: img === item.previewImg }"
@click="previewImg(img, item)"
>
<img :src="img" alt="">
<img :src="img" loading="lazy" decoding="async" alt="">
</div>
</div>
</div>

View File

@@ -6,6 +6,8 @@
v-if="store.storeLogo && !logoError"
class="store-logo"
:src="store.storeLogo"
loading="lazy"
decoding="async"
:alt="storeName"
@error="logoError = true"
/>
@@ -50,7 +52,7 @@
:key="item.id"
@click="goGoods(item)"
>
<img class="recommend-img" :src="item.thumbnail || item.small" :alt="item.goodsName" />
<img class="recommend-img" :src="item.thumbnail || item.small" loading="lazy" decoding="async" :alt="item.goodsName" />
<div class="recommend-info">
<p class="recommend-name">{{ item.goodsName }}</p>
<div class="recommend-meta">

View File

@@ -15,7 +15,7 @@
<span class="line btm-line"></span>
<p>{{ item.describe }}</p>
</div>
<img :src="item.img" width="170" height="170" alt="" />
<img :src="item.img" loading="lazy" decoding="async" width="170" height="170" alt="" />
</div>
</div>
</template>

View File

@@ -17,7 +17,7 @@
<p>{{ item.name }}</p>
<p class="describe">{{ item.describe }}</p>
</div>
<img :src="item.img" alt="" />
<img :src="item.img" loading="lazy" decoding="async" alt="" />
</div>
</div>
</div>
@@ -39,7 +39,7 @@
<p>{{ item.name }}</p>
<p class="describe">{{ item.describe }}</p>
</div>
<img :src="item.img" alt="" />
<img :src="item.img" loading="lazy" decoding="async" alt="" />
</div>
</div>
</div>
@@ -58,7 +58,7 @@
@click="linkTo(item.url)"
>
<div class="img-wrap">
<img :src="item.img" alt="" />
<img :src="item.img" loading="lazy" decoding="async" alt="" />
<div class="jiaobiao" :class="'jiaobiao' + (index + 1)">
{{ index + 1 }}
</div>

View File

@@ -22,7 +22,7 @@
class="hover-pointer"
@click="linkTo(item.url)"
>
<img :src="item.img" width="210" height="210" :alt="item.name" />
<img :src="item.img" loading="lazy" decoding="async" width="210" height="210" :alt="item.name" />
<p>{{ item.name }}</p>
<p>
<span>{{ $filters.unitPrice(Number(item.price), "¥") }}</span>

View File

@@ -7,7 +7,7 @@
</div>
<div class="content-left">
<div>
<img class="hover-pointer" @click="linkTo(msgLeft.list[0].url)" :src="msgLeft.list[0].img" width="160" height="160" alt="" />
<img class="hover-pointer" @click="linkTo(msgLeft.list[0].url)" :src="msgLeft.list[0].img" loading="lazy" decoding="async" width="160" height="160" alt="" />
<div class="margin-left">{{ msgLeft.list[0].name }}</div>
<div class="margin-left">{{ msgLeft.list[0].describe }}</div>
<el-button
@@ -21,7 +21,7 @@
<div>
<template v-for="(item, index) in msgLeft.list">
<div v-if="index != 0" :key="index" @click="linkTo(item.url)" class="hover-pointer">
<img :src="item.img" width="80" height="80" alt="" />
<img :src="item.img" loading="lazy" decoding="async" width="80" height="80" alt="" />
<div>
<div>{{ item.name }}</div>
<div>{{ item.describe }}</div>
@@ -50,7 +50,7 @@
<span>{{ item.describe }}</span>
</div>
<div class="right-img">
<img :src="item.img" alt="" />
<img :src="item.img" loading="lazy" decoding="async" alt="" />
</div>
</div>
</div>

View File

@@ -19,7 +19,7 @@
class="content hover-pointer"
@click.stop="goToSeckill"
>
<img :src="item.goodsImage" width="140" height="140" :alt="item.goodsName" />
<img :src="item.goodsImage" loading="lazy" decoding="async" width="140" height="140" :alt="item.goodsName" />
<div class="ellipsis">{{ item.goodsName }}</div>
<div>
<span>{{ $filters.unitPrice(item.price, "¥") }}</span>

View File

@@ -3,7 +3,7 @@
<div class="for-your">{{ data.options.title }}</div>
<div class="flex card">
<div class="left hover-pointer" @click="linkTo(data.options.data.image.url)">
<img :src="data.options.data.image.src" alt="" />
<img :src="data.options.data.image.src" loading="lazy" decoding="async" alt="" />
</div>
<div class="right flex">
<!-- 商品区 -->
@@ -18,7 +18,7 @@
<div class="goods-name">{{ item.title }}</div>
<div class="goods-desc">{{ item.desc }}</div>
</div>
<img class="goods-img" :src="item.img" alt="" />
<img class="goods-img" :src="item.img" loading="lazy" decoding="async" alt="" />
</div>
</div>
<!-- 热卖区 -->
@@ -30,7 +30,7 @@
:key="index"
@click="linkTo(item.url)"
>
<img :src="item.img" alt="" />
<img :src="item.img" loading="lazy" decoding="async" alt="" />
<div class="hot-goods">
<div class="hot-goods-title">{{ item.title }}</div>
<div>

View File

@@ -26,7 +26,7 @@
@click="linkTo(item.url)"
>
<div class="goods-img">
<img :src="item.img" />
<img :src="item.img" loading="lazy" decoding="async" />
</div>
<div>
<div class="goods-name wes-2">{{ item.title }}</div>

View File

@@ -1,7 +1,7 @@
<template>
<div class="mix-panel flex" v-if="data.options.right.model == 'brand'">
<div class="left-side hover-pointer" @click="linkTo(data.options.right.data.image.url)">
<img :src="data.options.right.data.image.src" alt="" />
<img :src="data.options.right.data.image.src" loading="lazy" decoding="async" alt="" />
</div>
<div class="right-side">
<div class="badge-box flex">
@@ -17,7 +17,7 @@
v-for="(item, index) in data.options.right.data.list"
>
<div class="goods-thumbnail">
<img :src="item.img" alt="" />
<img :src="item.img" loading="lazy" decoding="async" alt="" />
</div>
</div>
</div>

View File

@@ -1,7 +1,7 @@
<template>
<div class="mix-panel flex" v-if="data.options.left.model == 'goods'">
<div class="left-side hover-pointer" @click="linkTo(data.options.left.data.image.url)">
<img :src="data.options.left.data.image.src" alt="" />
<img :src="data.options.left.data.image.src" loading="lazy" decoding="async" alt="" />
</div>
<div class="right-side">
<div class="badge-box flex">
@@ -17,7 +17,7 @@
v-for="(item, index) in data.options.left.data.list"
>
<div class="goods-thumbnail">
<img :src="item.img" alt="" />
<img :src="item.img" loading="lazy" decoding="async" alt="" />
</div>
<div class="goods-detail">
<div class="goods-detail-title">{{ item.title }}</div>

View File

@@ -6,7 +6,7 @@
:key="index"
@click="linkTo(item.url)"
>
<img :src="item.img" class="three-column-img" alt="" />
<img :src="item.img" loading="lazy" decoding="async" class="three-column-img" alt="" />
</div>
</div>
</template>

View File

@@ -13,7 +13,7 @@
<div class="goods-desc">{{ item.desc }}</div>
</div>
<div class="goods-img">
<img :src="item.img" />
<img :src="item.img" loading="lazy" decoding="async" />
</div>
</div>
</div>

View File

@@ -111,6 +111,8 @@
goods.goodsSku.thumbnail ||
'../assets/images/goodsDetail/item-detail-1.jpg'
"
loading="lazy"
decoding="async"
/>
<div>
<p>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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'"
/>

View File

@@ -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=""> &nbsp;{{ 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=""> &nbsp;{{ 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>

View File

@@ -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 {

View File

@@ -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'"
/>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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 }}

View File

@@ -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=""

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;

View File

@@ -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'"
/>

View File

@@ -216,6 +216,8 @@
<img
@click="goodsDetail(goods.skuId, goods.goodsId)"
:src="goods.image"
loading="lazy"
decoding="async"
alt=""
/>
<p

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -1,11 +1,173 @@
import ElementPlus from "element-plus";
import zhCn from "element-plus/es/locale/lang/zh-cn";
import "element-plus/dist/index.css";
// 组件样式(css.mjs 会自动传递 base/overlay/scrollbar/popper 等依赖样式)
import "element-plus/es/components/affix/style/css";
import "element-plus/es/components/alert/style/css";
import "element-plus/es/components/avatar/style/css";
import "element-plus/es/components/breadcrumb/style/css";
import "element-plus/es/components/breadcrumb-item/style/css";
import "element-plus/es/components/button/style/css";
import "element-plus/es/components/card/style/css";
import "element-plus/es/components/carousel/style/css";
import "element-plus/es/components/carousel-item/style/css";
import "element-plus/es/components/cascader/style/css";
import "element-plus/es/components/checkbox/style/css";
// container 的 css 会带上 aside/header/main/footer 全部布局组件样式
import "element-plus/es/components/container/style/css";
import "element-plus/es/components/date-picker/style/css";
import "element-plus/es/components/dialog/style/css";
import "element-plus/es/components/divider/style/css";
import "element-plus/es/components/drawer/style/css";
import "element-plus/es/components/dropdown/style/css";
import "element-plus/es/components/dropdown-item/style/css";
import "element-plus/es/components/dropdown-menu/style/css";
import "element-plus/es/components/empty/style/css";
import "element-plus/es/components/form/style/css";
import "element-plus/es/components/form-item/style/css";
import "element-plus/es/components/icon/style/css";
import "element-plus/es/components/image/style/css";
import "element-plus/es/components/input/style/css";
import "element-plus/es/components/input-number/style/css";
import "element-plus/es/components/menu/style/css";
import "element-plus/es/components/menu-item/style/css";
import "element-plus/es/components/option/style/css";
import "element-plus/es/components/pagination/style/css";
import "element-plus/es/components/progress/style/css";
import "element-plus/es/components/radio/style/css";
import "element-plus/es/components/radio-button/style/css";
import "element-plus/es/components/radio-group/style/css";
import "element-plus/es/components/rate/style/css";
import "element-plus/es/components/select/style/css";
import "element-plus/es/components/skeleton/style/css";
import "element-plus/es/components/step/style/css";
import "element-plus/es/components/steps/style/css";
import "element-plus/es/components/sub-menu/style/css";
import "element-plus/es/components/switch/style/css";
import "element-plus/es/components/tab-pane/style/css";
import "element-plus/es/components/table/style/css";
import "element-plus/es/components/table-column/style/css";
import "element-plus/es/components/tabs/style/css";
import "element-plus/es/components/tag/style/css";
import "element-plus/es/components/tooltip/style/css";
import "element-plus/es/components/upload/style/css";
// JS 服务样式(ElMessage/ElMessageBox 在调用处显式 import,这里只需样式)
import "element-plus/es/components/message/style/css";
import "element-plus/es/components/message-box/style/css";
import "element-plus/es/components/loading/style/css";
import "@/assets/styles/element.scss";
import {
ElAffix,
ElAlert,
ElAvatar,
ElBreadcrumb,
ElBreadcrumbItem,
ElButton,
ElCard,
ElCarousel,
ElCarouselItem,
ElCascader,
ElCheckbox,
// ElContainer 的 install 会同时注册 ElAside/ElHeader/ElMain/ElFooter;
// 单独 app.use(ElAside)/app.use(ElMain) 是 noop(withNoopInstall),不会注册
ElContainer,
ElDatePicker,
ElDialog,
ElDivider,
ElDrawer,
ElDropdown,
ElDropdownItem,
ElDropdownMenu,
ElEmpty,
ElForm,
ElFormItem,
ElIcon,
ElImage,
ElInput,
ElInputNumber,
ElMenu,
ElMenuItem,
ElOption,
ElPagination,
ElProgress,
ElRadio,
ElRadioButton,
ElRadioGroup,
ElRate,
ElSelect,
ElSkeleton,
ElStep,
ElSteps,
ElSubMenu,
ElSwitch,
ElTabPane,
ElTable,
ElTableColumn,
ElTabs,
ElTag,
ElTooltip,
ElUpload,
ElLoading,
provideGlobalConfig,
} from "element-plus";
const components = [
ElAffix,
ElAlert,
ElAvatar,
ElBreadcrumb,
ElBreadcrumbItem,
ElButton,
ElCard,
ElCarousel,
ElCarouselItem,
ElCascader,
ElCheckbox,
// ElContainer 的 install 会同时注册 ElAside/ElHeader/ElMain/ElFooter;
// 单独 app.use(ElAside)/app.use(ElMain) 是 noop(withNoopInstall),不会注册
ElContainer,
ElDatePicker,
ElDialog,
ElDivider,
ElDrawer,
ElDropdown,
ElDropdownItem,
ElDropdownMenu,
ElEmpty,
ElForm,
ElFormItem,
ElIcon,
ElImage,
ElInput,
ElInputNumber,
ElMenu,
ElMenuItem,
ElOption,
ElPagination,
ElProgress,
ElRadio,
ElRadioButton,
ElRadioGroup,
ElRate,
ElSelect,
ElSkeleton,
ElStep,
ElSteps,
ElSubMenu,
ElSwitch,
ElTabPane,
ElTable,
ElTableColumn,
ElTabs,
ElTag,
ElTooltip,
ElUpload,
];
export function setupElementPlus(app) {
app.use(ElementPlus, {
locale: zhCn,
size: "default",
});
components.forEach((component) => app.use(component));
// 注册 v-loading 指令
app.use(ElLoading);
// 不使用 ConfigProvider,直接注入全局配置(locale/尺寸),行为与 app.use(ElementPlus, {...}) 一致
provideGlobalConfig({ locale: zhCn, size: "default" }, app, true);
}