Vue2.X はスワイパー カスタム ページャーを使用して無効をクリックし、スワイパーの次のカルーセル ページが事前にデジタルでスクロールします。

要件:
1. 3D チルト角度カルーセル
2. カスタム ページャー
3. カスタム ナビゲーションの左右ボタン
4. アニメーションは Lottfile を使用
5. スワイパーは現在のページまでスクロールし、デジタル ダイナミック スクロールを開始します
開発上の注意点
バージョンのインストール
1.npm install vue-awesome - [email protected]
2.npm install [email protected] --save
3.npm install vue-count-to
難易度分析
1. カスタム ページャーをクリックできます。
元々はカスタム ページャーでしたが、問題がありました (ページをクリック 切り替えなし) 多くの解決策を見つけましたが、うまくいきませんでした

        pagination: {
    
    
          el: ".swiper-pagination",
          clickable: true,
          type: "custom",
          //下面方法可以生成我们自定义的分页器到页面上
          renderCustom: function (swiper, current, total) {
    
    
            var paginationHtml = " ";
            for (var i = 0; i < total; i++) {
    
    
              // 判断是不是激活焦点,是的话添加active类,不是就只添加基本样式类
              if (i === current - 1) {
    
    
                paginationHtml += `<div class="swiper-pagination-customs swiper-pagination-customs-active"></div>`;
              } else {
    
    
                paginationHtml += `<div class="swiper-pagination-customs"></div>`;
              }
            }
            return paginationHtml;
          },
        },
	后来改变方案 使用原生的小圆点然后进行样式穿透
      pagination: {
    
    
          el: ".swiper-pagination",
          clickable: true,
          type: "bullets",
          //下面方法可以生成我们自定义的分页器到页面上
          // renderCustom: function (swiper, current, total) {
    
    
          //   var paginationHtml = " ";
          //   for (var i = 0; i < total; i++) {
    
    
          //     // 判断是不是激活焦点,是的话添加active类,不是就只添加基本样式类
          //     if (i === current - 1) {
    
    
          //       paginationHtml += `<div class="swiper-pagination-customs swiper-pagination-customs-active"></div>`;
          //     } else {
    
    
          //       paginationHtml += `<div class="swiper-pagination-customs"></div>`;
          //     }
          //   }
          //   return paginationHtml;
          // },
        },

2. 現在のスワイパー ページまでスクロールして、デジタル スクロールを開始します。最初は
、activeIndex が使用されていましたが、不正確であることが判明しました。その後、realIndex
スワイパーは dom をコピーし、コピーされたページはスクロールしません。this.slideToLoop(this.realIndex を追加) 、0、true) slideChangeTransitionEnd 関数内;
countTo コンポーネントに autoplay 属性を追加し、現在のインデックス ページにジャンプして endVal の値を変更して再読み込みします

 <countTo
                    :startVal="0"
                    :endVal="endValE"
                    :duration="2000"
                    autoplay
                    useEasing
                  ></countTo>

        on: {
    
    
          slideChangeTransitionEnd: function () {
    
    
            //轮播前获取当前swiper索引 activeIndex不准
            /**
             * realIndex 0  累计安装量 endValA
             * realIndex 1  累计售后服务量 endValB
             * realIndex 2  累计服务车企工单量 endValC
             * realIndex 3  电商服务工单量 endValD
             * realIndex 4 服务商平均安装时效 endValE
             * realIndex 5 评分图
             */
            // console.log(this.realIndex);
            this.slideToLoop(this.realIndex, 0, true); //防止loop:true 复制dom
            if (this.realIndex == 4) {
    
     //修复累计售后服务量滚动bug
              that.endValB = 0;
            }
            if (this.realIndex == 0) {
    
    
              //加载下一页的数据
              that.endValE = 0;
              that.endValB = that.orginB;
            }
            if (this.realIndex == 1) {
    
    
              that.endValC = that.orginC;
            }
            if (this.realIndex == 2) {
    
    
              that.endValD = that.orginD;
            }
            if (this.realIndex == 3) {
    
    
              that.endValE = that.orginE;
              that.endValA = 0;
            }
            if (this.realIndex == 4) {
    
    
              that.endValA = that.orginA;
            }
            if (this.realIndex == 5) {
    
    
              that.endValB = 0;
              that.endValC = 0;
              that.endValD = 0;
            }
          },
        },

完全なコード

<template>
  <div class="contain">
    <div class="top">主服数据总览</div>
    <div class="middle">
      <div class="swiper">
        <div class="swiper-item">
          <swiper :options="swiperOption" ref="mySwipers" class="swipers">
            <swiper-slide class="swiper_item">
              <!-- 具体内容 -->
              <div>
                <div class="image-bg animatea">
                  <div class="imageA"></div>
                  <div class="image-bg_bg"></div>
                </div>
                <div class="title">2023年服务商安装满意度</div>
                <div class="rate">
                  <div>整体评分</div>
                  <div>
                    <el-rate
                      v-model="value1"
                      disabled
                      disabled-void-color="#10264B"
                      :colors="colors"
                    ></el-rate>
                  </div>
                </div>
                <div class="rate">
                  <div>服务态度</div>
                  <div>
                    <el-rate
                      v-model="value1"
                      disabled
                      disabled-void-color="#10264B"
                      :colors="colors"
                    ></el-rate>
                  </div>
                </div>
                <div class="rate">
                  <div>联系时效</div>
                  <div>
                    <el-rate
                      v-model="value1"
                      disabled
                      disabled-void-color="#10264B"
                      :colors="colors"
                    ></el-rate>
                  </div>
                </div>
                <div class="rate">
                  <div>安装时效</div>
                  <div>
                    <el-rate
                      v-model="value1"
                      disabled
                      disabled-void-color="#10264B"
                      :colors="colors"
                    ></el-rate>
                  </div>
                </div>
              </div>
            </swiper-slide>
            <swiper-slide class="swiper_item">
              <!-- 具体内容 -->
              <div>
                <div class="image-bg animateb">
                  <div class="imageB"></div>
                  <div class="image-bg_bgs"></div>
                </div>
                <div class="title">2023年累计安装量</div>
                <div class="num">
                  <!-- {
    
    {
    
     String(123456789).replace(/(\d)(?=(\d{3})+$)/g, "$1,") }} -->
                  <countTo
                    :startVal="0"
                    :endVal="endValA"
                    :duration="2000"
                    autoplay
                  ></countTo>
                </div>
                <div class="titles">较上年同比 <span>+123.5%</span></div>
              </div>
            </swiper-slide>
            <swiper-slide class="swiper_item">
              <!-- 具体内容 -->
              <div>
                <div class="image-bg animatec">
                  <div class="imageC"></div>
                  <div class="image-bg_bgss"></div>
                </div>
                <div class="title">2023年累计售后服务量</div>
                <div class="num">
                  <!-- {
    
    {
    
     String(a).replace(/(\d)(?=(\d{3})+$)/g, "$1,") }} -->
                  <countTo
                    :startVal="0"
                    :endVal="endValB"
                    :duration="2000"
                    autoplay
                    useEasing
                  ></countTo>
                </div>
                <div class="titles">较上年同比 <span>+123.5%</span></div>
              </div>
            </swiper-slide>
            <swiper-slide class="swiper_item">
              <!-- 具体内容 -->
              <div>
                <div class="image-bg animatea">
                  <div class="imageD"></div>
                  <div class="image-bg_bg"></div>
                </div>
                <div class="title">2023年累计服务车企工单量</div>
                <div class="num">
                  <!-- {
    
    {
    
     String(a).replace(/(\d)(?=(\d{3})+$)/g, "$1,") }} -->
                  <countTo
                    :startVal="0"
                    :endVal="endValC"
                    :duration="2000"
                    autoplay
                    useEasing
                  ></countTo>
                </div>
                <div class="titles">较上年同比 <span>+123.5%</span></div>
              </div>
            </swiper-slide>
            <swiper-slide class="swiper_item">
              <!-- 具体内容 -->
              <div>
                <div class="image-bg animatec">
                  <div class="imageE"></div>
                  <div class="image-bg_bgs"></div>
                </div>
                <div class="title">2023年电商服务工单量</div>
                <div class="num">
                  <!-- {
    
    {
    
     String(a).replace(/(\d)(?=(\d{3})+$)/g, "$1,") }} -->
                  <countTo
                    :startVal="0"
                    :endVal="endValD"
                    :duration="2000"
                    autoplay
                    useEasing
                  ></countTo>
                </div>
                <div class="titles">较上年同比 <span>+123.5%</span></div>
              </div>
            </swiper-slide>
            <swiper-slide class="swiper_item">
              <!-- 具体内容 -->
              <div>
                <div class="image-bg">
                  <div class="imageF"></div>
                  <div class="image-bg_bgss animateb"></div>
                </div>
                <div class="title">2023年服务商平均安装时效</div>
                <div class="num">
                  <!-- {
    
    {
    
     String(a).replace(/(\d)(?=(\d{3})+$)/g, "$1,") }} -->
                  <countTo
                    :startVal="0"
                    :endVal="endValE"
                    :duration="2000"
                    autoplay
                    useEasing
                  ></countTo>
                </div>
                <div class="titles">较上年同比 <span>+123.5%</span></div>
              </div>
            </swiper-slide>
          </swiper>

          <!-- 指示器 -->
          <div class="swiper-button-next"></div>
          <div class="swiper-button-prev"></div>
        </div>

        <!-- 分页 -->
        <div class="swiper-pagination"></div>
        <!-- 动画 -->
        <div id="middle" class="animatew"></div>
      </div>
    </div>
    <div class="bottom"></div>
  </div>
</template>
<script>
import lottie from "lottie-web";
import animate from "./animate.json";
import countTo from "vue-count-to";
import {
    
     Swiper, SwiperSlide } from "vue-awesome-swiper";
import "swiper/css/swiper.css";
export default {
    
    
  data() {
    
    
    let that = this;
    return {
    
    
      swiperOption: {
    
    
        speed: 3000,
        effect: "coverflow",
        slidesPerView: 3, //一下子展示3个
        slidesPerGroup: 1, //每次只转动一张图片
        coverflowEffect: {
    
    
          rotate: -30, //侧转角度(负值凸出)
          stretch: -100, //控制展示swiper之间的距离
          depth: 250, //控制两边的大小缩放
          modifier: 1,
          shadows: true,
        },
        activeIndex: 0,
        loop: true,
        navigation: {
    
    
          // 左右按钮
          nextEl: ".swiper-button-next",
          prevEl: ".swiper-button-prev",
        },
        pagination: {
    
    
          el: ".swiper-pagination",
          clickable: true,
          type: "bullets",
          //下面方法可以生成我们自定义的分页器到页面上
          // renderCustom: function (swiper, current, total) {
    
    
          //   var paginationHtml = " ";
          //   for (var i = 0; i < total; i++) {
    
    
          //     // 判断是不是激活焦点,是的话添加active类,不是就只添加基本样式类
          //     if (i === current - 1) {
    
    
          //       paginationHtml += `<div class="swiper-pagination-customs swiper-pagination-customs-active"></div>`;
          //     } else {
    
    
          //       paginationHtml += `<div class="swiper-pagination-customs"></div>`;
          //     }
          //   }
          //   return paginationHtml;
          // },
        },
        observer: true,
        cache: false,
        observeParents: true,
        lazy: {
    
    
          loadPrevNext: false,
        },
        autoplay: {
    
    
          //自动播放
          delay: 2000,
          disableOnInteraction: false, //点击了还自动轮播
          stopOnLastSlide: false,
        },
        on: {
    
    
          slideChangeTransitionEnd: function () {
    
    
            //轮播前获取当前swiper索引 activeIndex不准
            /**
             * realIndex 0  累计安装量 endValA
             * realIndex 1  累计售后服务量 endValB
             * realIndex 2  累计服务车企工单量 endValC
             * realIndex 3  电商服务工单量 endValD
             * realIndex 4 服务商平均安装时效 endValE
             * realIndex 5 评分图
             */
            // console.log(this.realIndex);
            this.slideToLoop(this.realIndex, 0, true); //防止loop:true 复制dom
            if (this.realIndex == 4) {
    
     //修复累计售后服务量滚动bug
              that.endValB = 0;
            }
            if (this.realIndex == 0) {
    
    
              //加载下一页的数据
              that.endValE = 0;
              that.endValB = that.orginB;
            }
            if (this.realIndex == 1) {
    
    
              that.endValC = that.orginC;
            }
            if (this.realIndex == 2) {
    
    
              that.endValD = that.orginD;
            }
            if (this.realIndex == 3) {
    
    
              that.endValE = that.orginE;
              that.endValA = 0;
            }
            if (this.realIndex == 4) {
    
    
              that.endValA = that.orginA;
            }
            if (this.realIndex == 5) {
    
    
              that.endValB = 0;
              that.endValC = 0;
              that.endValD = 0;
            }
          },
        },
      },
      value1: 3,
      colors: ["#146C82", "#146C82", "#146C82"],
      endValA: 0,
      endValB: 0,
      endValC: 0,
      endValD: 0,
      endValE: 0,
      orginA: 1981000,
      orginB: 1981009,
      orginC: 981000,
      orginD: 981000,
      orginE: 981000,
      timer: null,
    };
  },
  mounted() {
    
    
    this.init();
    this.getList();
    // this.timer = setInterval(()=>{
    
    
    //   this.startVal +=1;
    // },3000)
  },
  components: {
    
    
    swiper: Swiper,
    swiperSlide: SwiperSlide,
    countTo: countTo,
  },
  // 计算属性
  computed: {
    
    
    // swiper() {
    
    
    //   return this.$refs["mySwipers"].$swiper;
    // },
  },
  watch: {
    
    },
  methods: {
    
    
    /**加载lottiefiles文件 */
    init() {
    
    
      const icon = document.getElementById("middle");
      lottie.loadAnimation({
    
    
        container: icon, // 包含动画的dom元素
        renderer: "svg", // 渲染出来的是什么格式
        loop: true, // 循环播放
        autoplay: true, // 自动播放
        animationData: animate, // 动画json的路径
      });
    },
    /**查询数据 */
    getList() {
    
    
      setTimeout(() => {
    
    
        // this.endValA = this.orginA;
        // this.endValB = this.orginB;
        // this.endValC = this.orginC;
        // this.endValD = this.orginD;
        // this.endValE = this.orginE;
      }, 3000);
    },
    callBack() {
    
    
      console.log("暂停计数");
    },
  },
};
</script>
<style lang="less" scoped>
@font-face {
    
    
  font-family: "DS-Digib";
  src: url("./images/DS-Digital.ttf");
}
.num {
    
    
  //需要更改的数字添加font-family属性
  font-family: "DS-Digib";
  font-size: 74px;
  color: #49eaff;
  margin-top: 20px;
}
.contain {
    
    
  height: 100%;
  width: 100%;
  background-size: 100% 100%;
  background-attachment: fixed;
  box-sizing: border-box;
  position: relative;
  background-color: #0d1322;
  padding: 39px 22px 11px 19px;
  z-index: 100;
  .top {
    
    
    width: 100%;
    height: 67px;
    background: url("./images/top.png");
    background-size: 100% 100%;
    font-size: 44px;
    font-family: HuXiaoBo-NanShen, HuXiaoBo;
    font-weight: normal;
    color: #ffffff;
    line-height: 46px;
    box-sizing: border-box;
    letter-spacing: 7px;
    text-align: center;
  }
  .middle {
    
    
    width: 100%;
    height: calc(100% - 123px);
    box-sizing: border-box;
    background: transparent;
    .swiper {
    
    
      width: 100%;
      height: 100%;
      color: #ffffff;
      background: transparent;
      position: relative;
      .swiper-item {
    
    
        position: absolute;
        width: 80%;
        height: 394px;
        top: 12%;
        left: 50%;
        transform: translateX(-50%);
        // z-index: 100;
        .swipers {
    
    
          width: 100%;
          height: 100%;
          // border: 1px solid blue;
          .swiper_item {
    
    
            width: 400px;
            height: 394px;
            background: url("./images/swiper-bg.png");
            background-size: 100% 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            > div {
    
    
              width: 450px;
              height: 360px;
              // border: 1px solid red;
              display: flex;
              flex-direction: column;
              align-items: center;
              .rate {
    
    
                display: flex;
                font-size: 14px;
                // color: rgba(20,108,129,1);
                color: #49eaff;
                margin-top: 10px;
                align-items: center;
                height: 40px;
                > div {
    
    
                  &:nth-child(1) {
    
    
                    margin-right: 10px;
                  }
                }
              }
              .image-bg {
    
    
                width: 132px;
                height: 119px;
                display: flex;
                align-items: center;
                justify-content: center;
                position: relative;
                margin-top: 20px;
              }
              .title {
    
    
                font-size: 20px;
                color: #49eaff;
                font-weight: 400;
                margin-top: 20px;
              }
              .titles {
    
    
                font-size: 18px;
                font-weight: 400;
                color: #49eaff;
                margin-top: 20px;
                // >span{
    
    
                //   font-family: "DS-Digib";
                // }
              }
              .image-bg_bg {
    
    
                width: 132px;
                height: 119px;
                background: url("./images/bga.png");
                background-size: 100% 100%;
                position: absolute;
                top: 0;
                left: 0;
                animation: move 1s infinite alternate;
              }
              .image-bg_bgs {
    
    
                width: 132px;
                height: 119px;
                background: url("./images/bga.png");
                background-size: 100% 100%;
                position: absolute;
                top: 0;
                left: 0;
                animation: move 1s infinite 0.5s alternate;
              }
              .image-bg_bgss {
    
    
                width: 132px;
                height: 119px;
                background: url("./images/bga.png");
                background-size: 100% 100%;
                position: absolute;
                top: 0;
                left: 0;
                animation: move 1s infinite 1s alternate;
              }

              .imageA {
    
    
                width: 41px;
                height: 36px;
                background: url("./images/66.png");
                background-size: 100% 100%;
              }
              .imageB {
    
    
                width: 40px;
                height: 40px;
                background: url("./images/11.png");
                background-size: 100% 100%;
              }
              .imageC {
    
    
                width: 41px;
                height: 41px;
                background: url("./images/22.png");
                background-size: 100% 100%;
              }
              .imageD {
    
    
                width: 39px;
                height: 32px;
                background: url("./images/33.png");
                background-size: 100% 100%;
              }
              .imageE {
    
    
                width: 41px;
                height: 41px;
                background: url("./images/44.png");
                background-size: 100% 100%;
              }
              .imageF {
    
    
                width: 39px;
                height: 39px;
                background: url("./images/55.png");
                background-size: 100% 100%;
              }
            }
          }
        }
      }
      .animatew {
    
    
        width: 70%;
        height: 650px;
        position: absolute;
        top: 30%;
        left: 50%;
        transform: translateX(-50%);
        // border: 1px solid #FFFFFF;
      }
    }
  }

  .swiper-button-next {
    
    
    background: url("./images/next.png");
    background-size: 100% 100%;
    --swiper-navigation-size: 90px;
    z-index: 10000 !important;
  }
  .swiper-button-prev {
    
    
    background: url("./images/pre.png");
    background-size: 100% 100%;
    --swiper-navigation-size: 90px;
    z-index: 1000000 !important;
  }
  /**自定义分页的样式 */
  .swiper-pagination {
    
    
    width: 70%;
    height: 94px;
    background: transparent;
    position: absolute;
    display: flex;
    justify-content: space-between;
    bottom: 50px;
    z-index: 1000;
    left: 50%;
    transform: translateX(-50%);
  }
  .swiper-pagination-custom {
    
    
    height: 94px;
    text-align: end !important; //这里设置分页器的位置 放在行的末尾
  }
  /*自定义分页器的样式*/
  .swiper-pagination /deep/ .swiper-pagination-bullet:nth-of-type(1) {
    
    
    width: 93px;
    height: 94px;
    display: inline-block;
    border-radius: 5px;
    margin: 0 3px;
    outline: 0;
    background: url("./images/1.png");
    background-size: 100% 100%;
    box-sizing: border-box;
    opacity: 1;
  }
  .swiper-pagination /deep/ .swiper-pagination-bullet:nth-of-type(2) {
    
    
    width: 93px;
    height: 94px;
    display: inline-block;
    border-radius: 5px;
    margin: 0 3px;
    outline: 0;
    background: url("./images/2.png");
    background-size: 100% 100%;
    box-sizing: border-box;
    opacity: 1;
  }
  .swiper-pagination /deep/ .swiper-pagination-bullet:nth-of-type(3) {
    
    
    width: 93px;
    height: 94px;
    display: inline-block;
    border-radius: 5px;
    margin: 0 3px;
    outline: 0;
    background: url("./images/3.png");
    background-size: 100% 100%;
    box-sizing: border-box;
    opacity: 1;
  }
  .swiper-pagination /deep/ .swiper-pagination-bullet:nth-of-type(4) {
    
    
    width: 93px;
    height: 94px;
    display: inline-block;
    border-radius: 5px;
    margin: 0 3px;
    outline: 0;
    background: url("./images/4.png");
    background-size: 100% 100%;
    box-sizing: border-box;
    opacity: 1;
  }
  .swiper-pagination /deep/ .swiper-pagination-bullet:nth-of-type(5) {
    
    
    width: 93px;
    height: 94px;
    display: inline-block;
    border-radius: 5px;
    margin: 0 3px;
    outline: 0;
    background: url("./images/5.png");
    background-size: 100% 100%;
    box-sizing: border-box;
    opacity: 1;
  }
  .swiper-pagination /deep/ .swiper-pagination-bullet:nth-of-type(6) {
    
    
    width: 93px;
    height: 94px;
    display: inline-block;
    border-radius: 5px;
    margin: 0 3px;
    outline: 0;
    background: url("./images/6.png");
    background-size: 100% 100%;
    box-sizing: border-box;
    opacity: 1;
  }
  // .swiper-pagination-customs:last-child {
    
    
  //   margin-right: 16px;
  // }
  /*自定义分页器激活时的样式表现*/
  .swiper-pagination /deep/ .swiper-pagination-bullet-active {
    
    
    box-shadow: 0px 0px 20px 5px rgba(62, 144, 255, 0.5);
    width: 93px;
    height: 94px;
  }

  .bottom {
    
    
    position: absolute;
    width: calc(100% - 41px);
    height: 67px;
    background: url("./images/foot.png");
    background-size: 100% 100%;
    box-sizing: border-box;
    bottom: 0;
    left: 19px;
  }
}
/deep/ .el-rate__icon {
    
    
  font-size: 22px;
}

@keyframes move {
    
    
  from {
    
    
    transform: rotate(180deg);
  }
  to {
    
    
    transform: rotate(360deg);
  }
}
</style>

ディスプレイ効果
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_44705979/article/details/129362121