升级Vue3,iView替换ElementPlus

- 删除babel配置、更新依赖与入口初始化
- 全量替换UI组件、样式适配,新增迁移文档与标签/过滤器自动化替换脚本
This commit is contained in:
lifenlong
2026-06-05 17:49:43 +08:00
parent 615ee91511
commit 832fda813b
322 changed files with 25693 additions and 24453 deletions

View File

@@ -1,10 +1,9 @@
<template>
<div class="model-form">
<div class="model-content">
<template v-for="(element, index) in data.list">
<template v-for="(element, index) in data.list" :key="element.key || index">
<model-form-item
v-if="element && element.key"
:key="element.key"
:element="element"
:index="index"
:data="data"

View File

@@ -29,12 +29,11 @@
/>
</div>
<ul class="advert-list width_1200_auto">
<template v-for="(item, index) in element.options.list">
<template v-for="(item, index) in element.options.list" :key="index">
<li
v-if="index !== 0"
@click="linkTo(item.url)"
class="hover-pointer"
:key="index"
>
<img :src="item.img" width="230" height="190" alt="" />
</li>

View File

@@ -6,17 +6,17 @@
<div class="nav-content">
<!-- 轮播图 -->
<!-- autoplay autoplay-speed="10000"-->
<Carousel :height="333.9" autoplay :autoplay-speed="5000">
<CarouselItem v-for="(item, index) in data.options.list" :key="index">
<div class="swiper-img" >
<el-carousel height="334px" :interval="5000">
<el-carousel-item v-for="(item, index) in data.options.list" :key="index">
<div class="swiper-img">
<img
:src="item.img"
@click="linkTo(item.url)"
class="hover-pointer"
/>
</div>
</CarouselItem>
</Carousel>
</el-carousel-item>
</el-carousel>
</div>
<div class="nav-right">
<div class="person-msg">
@@ -24,7 +24,7 @@
<img class="user-face" :src="userInfo.face || defaultAvatar" alt />
<div class="welcome">
Hi, {{
userInfo.nickName || `欢迎来到${config.title}` | secrecyMobile
$filters.secrecyMobile(userInfo.nickName || `欢迎来到${config.title}`)
}}
</div>
</div>

View File

@@ -5,13 +5,13 @@
<div class="nav-side"></div>
<div class="nav-content">
<!-- 轮播图 -->
<Carousel autoplay @on-change="autoChange">
<CarouselItem v-for="(item, index) in data.options.list" :key="index" >
<el-carousel height="470px" :interval="5000" @change="autoChange">
<el-carousel-item v-for="(item, index) in data.options.list" :key="index">
<div style="overflow: hidden">
<img :src="item.img" width="1200" height="470" />
</div>
</CarouselItem>
</Carousel>
</el-carousel-item>
</el-carousel>
</div>
</div>
</div>
@@ -34,8 +34,8 @@ export default {
},
methods: {
// 自动切换时改变背景色
autoChange (oVal, val) {
this.bgColor = this.data.options.list[val].bgColor
autoChange (index) {
this.bgColor = this.data.options.list[index].bgColor
}
}
};

View File

@@ -5,18 +5,17 @@
<div class="nav-side"></div>
<div class="nav-content">
<!-- 轮播图 -->
<Carousel autoplay>
<CarouselItem v-for="(item, index) in data.options.list" :key="index">
<el-carousel height="470px" :interval="5000">
<el-carousel-item v-for="(item, index) in data.options.list" :key="index">
<div style="overflow: hidden">
<img :src="item.img" width="590" height="470" />
</div>
</CarouselItem>
</Carousel>
</el-carousel-item>
</el-carousel>
</div>
<div class="nav-content1">
<!-- 轮播图 -->
<Carousel autoplay :autoplay-speed="5000">
<CarouselItem v-for="(item, index) in data.options.listRight" :key="index">
<el-carousel height="470px" :interval="5000">
<el-carousel-item v-for="(item, index) in data.options.listRight" :key="index">
<div class="mb_10">
<img :src="item[0].img" width="190" height="150" />
</div>
@@ -26,19 +25,19 @@
<div>
<img :src="item[2].img" width="190" height="150" />
</div>
</CarouselItem>
</Carousel>
</el-carousel-item>
</el-carousel>
</div>
<div class="nav-right">
<div class="person-msg">
<img :src="userInfo.face" v-if="userInfo.face" alt />
<Avatar icon="ios-person" class="mb_10" v-else size="80" />
<div>Hi{{ userInfo.nickName || `欢迎来到${config.title}` | secrecyMobile }}</div>
<el-avatar v-else :size="80" class="mb_10"><el-icon><User /></el-icon></el-avatar>
<div>Hi{{ $filters.secrecyMobile(userInfo.nickName || `欢迎来到${config.title}`) }}</div>
<div v-if="userInfo.id">
<Button type="error" shape="circle">会员中心</Button>
<el-button type="danger" shape="circle">会员中心</el-button>
</div>
<div v-else>
<Button type="error" shape="circle">请登录</Button>
<el-button type="danger" shape="circle">请登录</el-button>
</div>
</div>
<div class="shop-msg">
@@ -60,7 +59,9 @@
import {articleList} from '@/api/common.js'
import storage from '@/plugins/storage';
import { User } from '@element-plus/icons-vue';
export default {
components: { User },
name: 'modelCarousel2',
props: ['data'],
data () {
@@ -163,7 +164,7 @@ export default {
margin-top: 10px;
}
.ivu-btn-default {
.el-button--default {
color: $theme_color;
border-color: $theme_color;
}

View File

@@ -4,8 +4,7 @@
<div class="top-header" :style="{ background: options.left.bgColor }">
<span>{{ options.left.title }}</span>
<span @click="linkTo(options.left.url)" class="hover-pointer"
>{{ options.left.secondTitle }} &gt;</span
>
>{{ options.left.secondTitle }} &gt;</span>
</div>
<div class="content">
<div
@@ -27,8 +26,7 @@
<div class="top-header" :style="{ background: options.middle.bgColor }">
<span>{{ options.middle.title }}</span>
<span class="hover-pointer" @click="linkTo(options.middle.url)"
>{{ options.middle.secondTitle }} &gt;</span
>
>{{ options.middle.secondTitle }} &gt;</span>
</div>
<div class="content">
<div
@@ -50,8 +48,7 @@
<div class="top-header" :style="{ background: options.right.bgColor }">
<span>{{ options.right.title }}</span>
<span @click="linkTo(options.right.url)" class="hover-pointer"
>{{ options.right.secondTitle }} &gt;</span
>
>{{ options.right.secondTitle }} &gt;</span>
</div>
<div class="content">
<div
@@ -62,7 +59,7 @@
>
<img :src="item.img" alt="" />
<p>{{ item.name }}</p>
<p>{{ item.price | unitPrice("¥") }}</p>
<p>{{ $filters.unitPrice(item.price, "¥") }}</p>
<div class="jiaobiao" :class="'jiaobiao' + (index + 1)">
{{ index + 1 }}
</div>

View File

@@ -1,6 +1,6 @@
<template>
<div class="not-enough" ref="obtain" id="demo">
<Affix :offset-top="62" @on-change="change">
<el-affix :offset-top="62" @change="change">
<ul class="nav-bar" v-show="topSearchShow">
<li
v-for="(item, index) in conData.options.navList"
@@ -12,7 +12,7 @@
<p @click="gotoDemo">{{ item.desc }}</p>
</li>
</ul>
</Affix>
</el-affix>
<div class="content" v-if="showContent">
<div
v-for="(item, index) in conData.options.list[currentIndex]"
@@ -23,7 +23,7 @@
<img :src="item.img" width="210" height="210" :alt="item.name" />
<p>{{ item.name }}</p>
<p>
<span>{{ Number(item.price) | unitPrice("¥") }}</span>
<span>{{ $filters.unitPrice(Number(item.price), "¥") }}</span>
</p>
</div>
</div>

View File

@@ -10,12 +10,12 @@
<img class="hover-pointer" @click="linkTo(msgLeft.list[0].url)" :src="msgLeft.list[0].img" width="160" height="160" alt="" />
<div class="margin-left">{{ msgLeft.list[0].name }}</div>
<div class="margin-left">{{ msgLeft.list[0].describe }}</div>
<Button
<el-button
size="small"
:style="{ background: msgLeft.bgColor }"
@click="linkTo(msgLeft.list[0].url)"
class="fz_12 view-btn"
>点击查看</Button
>点击查看</el-button
>
</div>
<div>
@@ -36,8 +36,7 @@
<div class="head-recommend" :style="{ background: msgRight.bgColor }">
<span>{{ msgRight.title }}</span>
<span @click="linkTo(msgRight.url)" class="hover-pointer"
>{{ msgRight.secondTitle }}&gt;</span
>
>{{ msgRight.secondTitle }}&gt;</span>
</div>
<div class="content-right">
<div

View File

@@ -12,155 +12,105 @@
</div>
<div class="act-status" v-else>未开始</div>
</div>
<swiper :options="swiperOption" ref="mySwiper">
<swiper-slide v-for="(item,index) in goodsList" :key="index">
<div class="content hover-pointer" @click.stop="goToSeckill">
<img :src="item.goodsImage" width="140" height="140" :alt="item.goodsName">
<div class="ellipsis">{{item.goodsName}}</div>
<div>
<span>{{ item.price | unitPrice('¥') }}</span>
<span>{{ item.originalPrice | unitPrice('¥') }}</span>
</div>
<div class="goods-scroll">
<div
v-for="(item, index) in goodsList"
:key="index"
class="content hover-pointer"
@click.stop="goToSeckill"
>
<img :src="item.goodsImage" width="140" height="140" :alt="item.goodsName" />
<div class="ellipsis">{{ item.goodsName }}</div>
<div>
<span>{{ $filters.unitPrice(item.price, "¥") }}</span>
<span>{{ $filters.unitPrice(item.originalPrice, "¥") }}</span>
</div>
</swiper-slide>
<div class="swiper-button-prev" slot="button-prev">
<Icon type="ios-arrow-back" />
</div>
<div class="swiper-button-next" slot="button-next">
<Icon type="ios-arrow-forward" />
</div>
</swiper>
</div>
</div>
</template>
<script>
// 引入插件
import { swiper, swiperSlide } from 'vue-awesome-swiper';
import 'swiper/dist/css/swiper.css';
export default {
components: {
swiper,
swiperSlide
},
props: {
data: Object
data: Object,
},
data () {
data() {
return {
list: [], // 秒杀时段列表
goodsList: [], // 商品列表
actStatus: 0, // 0 未开始 1 进行中
actName: '限时秒杀', // 活动名称
currIndex: 0, // 当前时间段的下标
currHour: '00', // 当前秒杀场
diffSeconds: 0, // 倒计时秒数
hours: 0, // 小时
minutes: 0, // 分钟
seconds: 0, // 秒
interval: null, // 定时器
swiperOption: { // 轮播图参数
slidesPerView: 5,
// 设置点击箭头
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
}
}
list: [],
goodsList: [],
actStatus: 0,
actName: "限时秒杀",
currIndex: 0,
currHour: "00",
diffSeconds: 0,
hours: 0,
minutes: 0,
seconds: 0,
interval: null,
};
},
watch: {
currIndex (val) {
clearInterval(this.interval)
this.interval = null
this.countDown(val)
this.goodsList = this.list[val].seckillGoodsList
currIndex(val) {
clearInterval(this.interval);
this.interval = null;
this.countDown(val);
this.goodsList = this.list[val].seckillGoodsList;
},
diffSeconds (val) {
diffSeconds(val) {
const hours = Math.floor(val / 3600);
// 当前秒数 / 60向下取整
// 获取到所有分钟数 3600 / 60 = 60分钟
// 对60取模超过小时数的分钟数
const minutes = Math.floor(val / 60) % 60;
// 当前的秒数 % 60获取到 超过小时数、分钟数的秒数(秒数)
const seconds = val % 60;
this.hours = filteTime(hours)
this.minutes = filteTime(minutes)
this.seconds = filteTime(seconds)
this.hours = filteTime(hours);
this.minutes = filteTime(minutes);
this.seconds = filteTime(seconds);
if (val <= 0) {
clearInterval(this.interval)
this.interval = null
clearInterval(this.interval);
this.interval = null;
}
function filteTime (time) {
if (time < 10) {
return '0' + time
} else {
return time
}
function filteTime(time) {
return time < 10 ? "0" + time : time;
}
}
},
},
computed: {
swiper () { // 轮播组件
return this.$refs.mySwiper.swiper;
}
},
beforeDestroy () {
// 销毁前清除定时器
beforeUnmount() {
clearInterval(this.interval);
},
mounted () {
this.getListByDay()
mounted() {
this.getListByDay();
},
methods: {
goToSeckill () { // 跳转秒杀页面
let routeUrl = this.$router.resolve({
path: '/seckill'
});
window.open(routeUrl.href, '_blank');
goToSeckill() {
const routeUrl = this.$router.resolve({ path: "/seckill" });
window.open(routeUrl.href, "_blank");
},
countDown (currIndex) { // 倒计时
// 0点时间戳
let zeroTime = new Date(new Date().toLocaleDateString()).getTime();
let currTime = new Date().getTime()
countDown(currIndex) {
const zeroTime = new Date(new Date().toLocaleDateString()).getTime();
const currTime = new Date().getTime();
let actTime = 0;
let nowHour = new Date().getHours(); // 当前小时数
if (this.list[currIndex].timeLine > nowHour) { // 活动未开始
const nowHour = new Date().getHours();
if (this.list[currIndex].timeLine > nowHour) {
this.actStatus = 0;
actTime = zeroTime + this.list[currIndex].timeLine * 3600 * 1000
} else if (this.list[currIndex].timeLine <= nowHour) { // 活动进行中
actTime = zeroTime + this.list[currIndex].timeLine * 3600 * 1000;
} else if (this.list[currIndex].timeLine <= nowHour) {
this.actStatus = 1;
if (currIndex === this.list.length - 1) { // 如果是最后一个活动直到24点结束
actTime = zeroTime + 24 * 3600 * 1000
if (currIndex === this.list.length - 1) {
actTime = zeroTime + 24 * 3600 * 1000;
} else {
actTime = zeroTime + this.list[currIndex + 1].timeLine * 3600 * 1000
actTime = zeroTime + this.list[currIndex + 1].timeLine * 3600 * 1000;
}
}
this.currHour = this.list[this.currIndex].timeLine
this.diffSeconds = Math.floor((actTime - currTime) / 1000)
this.currHour = this.list[this.currIndex].timeLine;
this.diffSeconds = Math.floor((actTime - currTime) / 1000);
this.interval = setInterval(() => {
this.diffSeconds--
}, 1000)
this.diffSeconds--;
}, 1000);
},
getListByDay () { // 当天秒杀活动
// const list = [
// {
// timeLine: 18,
// seckillGoodsList: [
// {goodsImage: 'https://lilishop-oss.oss-cn-beijing.aliyuncs.com/a9593607de404546953055f279fd5d54.png', goodsName: 'dfsdgsdf', originalPrice: 39, price: 12},
// {goodsImage: 'https://lilishop-oss.oss-cn-beijing.aliyuncs.com/a9593607de404546953055f279fd5d54.png', goodsName: 'dfsdgsdf', originalPrice: 39, price: 12},
// {goodsImage: 'https://lilishop-oss.oss-cn-beijing.aliyuncs.com/a9593607de404546953055f279fd5d54.png', goodsName: 'dfsdgsdf', originalPrice: 39, price: 12},
// {goodsImage: 'https://lilishop-oss.oss-cn-beijing.aliyuncs.com/a9593607de404546953055f279fd5d54.png', goodsName: 'dfsdgsdf', originalPrice: 39, price: 12},
// {goodsImage: 'https://lilishop-oss.oss-cn-beijing.aliyuncs.com/a9593607de404546953055f279fd5d54.png', goodsName: 'dfsdgsdf', originalPrice: 39, price: 12},
// {goodsImage: 'https://lilishop-oss.oss-cn-beijing.aliyuncs.com/a9593607de404546953055f279fd5d54.png', goodsName: 'dfsdgsdf', originalPrice: 39, price: 12}
// ]
// }
// ]
this.list = this.data.options.list
this.goodsList = this.list[0].seckillGoodsList
console.log( this.goodsList)
this.countDown(this.currIndex)
}
}
getListByDay() {
this.list = this.data.options.list;
this.goodsList = this.list[0].seckillGoodsList;
this.countDown(this.currIndex);
},
},
};
</script>
<style lang="scss" scoped>
@@ -174,15 +124,13 @@ export default {
width: 190px;
height: 100%;
color: #fff;
background-image: url("../../../assets/images/seckillBg.png");
background: linear-gradient(180deg, #ff5c58 0%, #e84a46 100%);
.title {
width: 100%;
text-align: center;
font-size: 28px;
margin-top: 31px;
}
.hour {
margin-top: 90px;
text-align: center;
@@ -190,7 +138,6 @@ export default {
font-size: 18px;
}
}
.count-down {
margin: 10px 0 0 30px;
> span {
@@ -219,15 +166,21 @@ export default {
content: "";
}
}
.act-status {
margin: 10px 0 0 65px;
font-size: 20px;
}
}
.goods-scroll {
height: 260px;
flex: 1;
margin-left: 10px;
background-color: #fff;
display: flex;
overflow-x: auto;
}
.content {
width: 200px;
min-width: 200px;
display: flex;
justify-content: center;
align-items: center;
@@ -262,26 +215,12 @@ export default {
line-height: 24px;
display: flex;
text-align: center;
span:nth-child(1) {
color: #fff;
font-size: 16px;
width: 92px;
background-color: $theme_color;
position: relative;
&::before {
content: " ";
width: 0;
height: 0;
border-color: transparent white transparent transparent;
border-style: solid;
border-width: 24px 8px 0 0;
position: absolute;
top: 0;
left: 84px;
}
}
span:nth-child(2) {
color: #999;
width: 66px;
@@ -290,35 +229,4 @@ export default {
}
}
}
.swiper-container {
height: 260px;
width: 1000px;
margin-left: 10px;
background-color: #fff;
}
.swiper-button-prev, .swiper-button-next {
background: #ccc;
width: 25px;
height: 35px;
font-size: 16px;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.swiper-button-prev:hover, .swiper-button-next:hover {
background: #aaa;
}
.swiper-button-prev {
left: 0;
border-bottom-right-radius: 18px;
border-top-right-radius: 18px;
padding-right: 5px;
}
.swiper-button-next {
right: 0;
border-top-left-radius: 18px;
border-bottom-left-radius: 18px;
padding-left: 5px;
}
</style>

View File

@@ -34,7 +34,7 @@
<div class="hot-goods">
<div class="hot-goods-title">{{ item.title }}</div>
<div>
<div class="hot-price">{{ item.price | unitPrice }}</div>
<div class="hot-price">{{ $filters.unitPrice(item.price) }}</div>
</div>
</div>
</div>
@@ -84,10 +84,10 @@ export default {
border-top: 1.4px solid #e2e2e2;
}
&:hover {
::v-deep .goods-name {
:deep .goods-name {
color: $theme_color;
}
::v-deep .goods-desc {
:deep .goods-desc {
color: $theme_color;
}
}

View File

@@ -33,7 +33,7 @@
<div class="goods-desc">{{ item.desc }}</div>
</div>
<div class="goods-price">
{{ item.price | unitPrice("¥") }}
{{ $filters.unitPrice(item.price, "¥") }}
</div>
<!-- 查看 -->
<div class="white-shadow">

View File

@@ -6,7 +6,7 @@
<div class="right-side">
<div class="badge-box flex">
<div class="round">
<Icon type="ios-arrow-forward" />
<el-icon><ArrowRight /></el-icon>
</div>
@@ -23,6 +23,7 @@
</template>
<script>
import { ArrowRight } from '@element-plus/icons-vue';
export default {
name: "mix-goods",
data() {
@@ -34,7 +35,7 @@ export default {
default: {}
}
},
components: {},
components: { ArrowRight },
mounted() {
},

View File

@@ -17,7 +17,7 @@
</div>
<div class="goods-detail">
<div class="goods-detail-title">{{item.title}}</div>
<div class="goods-detail-price">{{item.price | unitPrice('¥')}}</div>
<div class="goods-detail-price">{{ $filters.unitPrice(item.price, '¥') }}</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,62 @@
.setup-content{
position: relative;
&:hover{
.setup-box{
display: block;
}
}
}
.setup-box{
display: none;
position: absolute;
top: 0;
left: 0;
background: rgba(0, 0, 0, .2);
z-index: 99;
width: 100%;
height: 100%;
.el-button{
float: right;
margin-right: 5px;
margin-top: 5px;
}
}
.modal-tab-bar{
margin-left: 20px;
table{
margin-top: 10px;
display:inline-block;
border: 1px solid #ddd;
border-radius: 5px;
max-height: 400px !important;
overflow: hidden auto;
}
thead{
background-color: #eee;
th{
padding: 5px 0;
}
}
td{
padding: 10px;
text-align: center;
}
tbody>tr:hover{
background-color: aliceblue;
}
}
.modal-top-advert{
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
>*{
margin-bottom: 10px;
}
.el-input{
width: 200px;
}
}