Carousel 的应用很广泛,基础用法这里不多做阐述,感兴趣的可以去element-gui了解Carousel 组件。
今天主要是梳理嵌套走马灯的逻辑,背景如下:
需要对项目做一个展示,项目可能有一个或多个,同时一个项目可能不包含标段,也可能包含一个或多个标段。
要求: 切换展示项目,若是项目包含标段,停止项目的切换,进行标段的切换(2个标段占用一个走马灯),当当前项目的标段信息切换到最后一页之后,切换下一个项目,一直这样轮回切换。
具体效果如下所示:
外层灰色框的是项目走马灯,里面嵌套的是标段走马灯。
代码如下:
<template>
<!-- 嵌套走马灯示例 :initial-index="projectIndex" bidAutoArr[key]-->
<el-carousel :interval="4000" type="card" width="1500px" height="230px" :autoplay="projectAuto" @change="projectPlayChange">
<el-carousel-item v-for="(item, key) in carouselData" :key="key">
<p>项目编号: {{item.projectCode}}</p>
<p>项目名称: {{item.projectName}}</p>
<div class="outer">
<el-carousel :interval="4000" type="card" height="100px" :autoplay="item.bidAutoplay" @change="bidPlayChange" ref="bidCarousel">
<el-carousel-item v-for="(bidSection, bidSectionKey) in item.bidSections" :key="bidSectionKey" class="content">
<p v-for="(bidInfo,bidInfoKey) in bidSection" :key="bidInfoKey">
{{bidInfo.bidSectionCode}} : {{bidInfo.bidSectionName}}
</p>
</el-carousel-item>
</el-carousel>
</div>
</el-carousel-item>
</el-carousel>
</template>
<script>
import data from '../dataMaked/CarouslDemo.json'
export default {
data(){
return {
carouselData: [], // 嵌套走马灯里需展示的数据
projectAuto: false, // 项目是否自动切换
projectIndex: 0, // 走马灯显示的当前项目的索引
}
},
methods: {
// 项目走马灯切换
projectPlayChange(proIndex) {
console.log('==================项目=============================');
console.log(proIndex);
this.projectAuto = false;
// 把上一页的项目的标段走马灯手动切换到第一页(不然上一页项目的标段走马灯是最后一页的状态)
console.log('pppppppppppppppppppppppppppppppppppppppppppppp');
console.log(this.$refs.bidCarousel[this.projectIndex]);
this.$refs.bidCarousel[this.projectIndex].setActiveItem(0);
// 更换项目索引为的当前项目
this.projectIndex = proIndex;
// 判断当前项目下标段走马灯数量,若是大于1,切标段;反之切项目
console.log(this.carouselData[this.projectIndex].bidSections.length);
if(this.carouselData[this.projectIndex].bidSections.length > 1) {
this.carouselData[this.projectIndex].bidAutoplay = true;
} else {
this.projectAuto = true;
}
},
// 标段走马灯切换
bidPlayChange(bidIndex) {
console.log('==================标段=============================');
console.log(bidIndex);
// 获取当前项目的标段走马灯数量
const BidCarouselNum = this.carouselData[this.projectIndex].bidSections.length;
// console.log(BidCarouselNum);
// 当前索引等于BidCarouselNum-1,意味着切到最后一张走马灯了
// 此时:判断项目长度,如果项目长度大于1,停止切标段,切项目;反之一直切换标段
if(bidIndex == BidCarouselNum-1 && this.carouselData.length > 1) {
this.carouselData[this.projectIndex].bidAutoplay = false;
this.projectAuto = true;
}
},
},
created() {},
mounted() {
// 数据格式重构--嵌套走马灯里需展示的数据
this.carouselData = this.$carouselInitData(data.res.kbProjectBidInfo);
console.log('111111111111111111111111111111111111111111111');
console.log(this.carouselData);
// 查看第一个项目的标段数量,如果标段数量大于1,从标段开始切换。
// 若是标段数量小于1,判断项目的个数,项目个数大于1,切项目;项目个数小于1,不动。
if(this.carouselData[0].bidSections.length > 1) {
this.carouselData[0].bidAutoplay = true;
} else {
if(this.carouselData.length > 1) {
this.projectAuto = true;
}
}
}
}
</script>
<style>
.el-carousel__item h3 {
color: #475669;
font-size: 14px;
opacity: 0.75;
line-height: 50px;
margin: 0;
}
.el-carousel__item:nth-child(2n) {
background-color: #99a9bf;
}
.el-carousel__item:nth-child(2n+1) {
background-color: #d3dce6;
}
.content:nth-child(2n) {
background-color: #1db418 !important;
}
.content:nth-child(2n+1) {
background-color: #d3361b !important;
}
.outer {
height: 100px;
width: 800px;
background: #3128b4;
margin: 10px auto;
}
</style>
主要用到的走马灯的属性:
属性 | 含义 |
---|---|
:autoplay | 是否自动切换走马灯 |
:interval | 走马灯自动切换的时间间隔 |
除此之外,还用到走马灯切换时触发的事件:@change
还用到手动切换走马灯的方法:setActiveItem
逻辑梳理起来很简单,由于我们是嵌套走马灯,所以优先需要生成嵌套走马灯需要的数据格式,由此,我封装了一个方法。
/**
* @Author: zhl
* @Date: 2021-03-04
* @Description: 生成两个嵌套跑马灯显示的项目及标段信息
* @param {*} originData 表示项目信息数组
* @param {*} bidNum 表示内层每个跑马灯显示的标段数量,不传参数就使用默认值:2
*/
var carouselInitData = function(originData, bidNum=2) {
var newData = [];
for(let i=0; i < originData.length; i++) {
var info = {}; // 包含项目和标段信息的对象
info.projectCode = originData[i].projectCode; // 项目编号
info.projectName = originData[i].projectName; // 项目名称
info.bidSections = []; // 内嵌走马灯每页显示标段信息(将原来的一维数组转化为二维数组)
if(originData[i].gtvBidSection && originData[i].gtvBidSection.length > 0) { // 先判断该项目有没有标段
var bidSectionNum = Math.ceil(originData[i].gtvBidSection.length / bidNum);
for(let j=0; j < bidSectionNum; j++) {
var bidSection = originData[i].gtvBidSection.slice(j*bidNum, (j+1)*bidNum);
info.bidSections.push(JSON.parse(JSON.stringify(bidSection)));
}
}
info.bidAutoplay = false; // 默认设置内层跑马灯(包含标段信息的)不切换
newData.push(JSON.parse(JSON.stringify(info)));
}
return newData;
}
export default carouselInitData;
对应的生成数据之后,就可以进行切换了:
首先 ,将项目和标段的自动切换设置为false,即:projectAuto: false ,由 carouselInitData 方法重构的数据也将所有项目的标段的自动切换设置为false了。
然后,进行切换的初始触发,在 mounted 钩子函数里面做一个判断:查看第一个项目的标段数量,如果标段数量大于1,从标段开始切换。若是标段数量小于1,判断项目的个数,项目个数大于1,切项目;项目个数小于1,不动。
其次 ,标段走马灯切换方法编写,如果项目有标段,且进行了标段的切换,如果切换到最后一张走马灯,且当前项目数量大于1,则停止当前项目标段的切换,切换到下一个项目。
最后 ,项目走马灯切换方法编写,项目切换之后,触发 projectPlayChange 方法,此时,优先停止项目的切换,同时将上一个项目的标段走马灯手动切换到第一页。然后判断当前项目下标段走马灯的数量,若是大于1,切标段;反之切项目。
这样就构成了一个循环,也实现了最终的切换效果。
原理其实就是:动态修改两个嵌套走马灯的 autoplay 属性。