嵌套走马灯Carousel


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 属性。


文章作者: 木华
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 木华 !
评论