vue.js

关注公众号 jb51net

关闭
首页 > 网络编程 > JavaScript > javascript类库 > vue.js > vue列表自动无限循环

vue组件实现列表自动无限循环的方法

作者:The ever Boy

最近刚好有个功能需要实现列表的无限循环滚动,这篇文章主要给大家介绍了关于vue组件实现列表自动无限循环的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前述:

用过vue-seamless-scroll插件,手动滚动列表到底部出现了空白现象,某些表现不符合项目场景,故自己写了一个自己用的组件,如果有人需要可以直接拿去用,如有不足请指教勿喷!

主要功能:

效果图 :

组件代码: 

<template>
  <div class="scroll-outer" ref="outer" @mouseover="onMouseover" @mouseleave="onMouseleave">
    <div class="scroll-inner-box" ref="scrollBox">
      <div class="scroll-item-box" ref="scrollItemBox">
        <slot></slot>
      </div>
      <div v-if="showSecond" class="scroll-item-box">
        <slot></slot>
      </div>
    </div>
  </div>
</template>
  <script>
export default {
  name: "my-auto-scroll",
  props: {
    list: {
      type: Array,
      default: () => [
        { name: "张三1" },
        { name: "张三2" },
        { name: "张三3" },
        { name: "张三4" },
        { name: "张三5" },
        { name: "张三6" },
        { name: "张三7" },
        { name: "张三8" },
        { name: "张三9" },
        { name: "张三10" },
      ],
    },
    speed: {
      type: Number,
      default: 0.1,
    },
    //滚动作单步运动时的单纯运动距离
    singleHeight: {
      type: Number,
      default: 0,
    },
    //单步运动的时间间隔
    waitTime: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      rafId: null,
      y: 0,
      showSecond: false,
      controleHeight: 0,
    };
  },
  watch: {
    list: {
      handler(newVal) {
        var that = this;
        this.$nextTick(() => {
          console.log(newVal);
          if (newVal && newVal.length > 0) {
            let scrollBox = that.$refs.scrollBox;
            let outer = that.$refs.outer;

            if (this.myReq) {
              cancelAnimationFrame(this.myReq);
            }
            // 开启动画
            if (this.canRun()) this.reqAnimationFrame();
            // this.reqAnimationFrame();
            // 手动滚动到底部时滚动条重置到最上边,同时滚动盒子重置为top:0
            outer.addEventListener("scroll", function () {
              if (
                outer.scrollTop + outer.clientHeight + 4 >=
                outer.scrollHeight
              ) {
                outer.scrollTop = 0;
                that.y = 0;
                scrollBox.style.top = 0;
              }
            });
          }
        });
      },
      deep: true,
      immediate: true,
    },
  },
  mounted() {
    window.addEventListener("resize", this.listenResizeFn);
  },
  methods: {
    listenResizeFn() {
      cancelAnimationFrame(this.myReq);
      if (this.canRun()) this.reqAnimationFrame();
    },
    onMouseover() {
      clearTimeout(this.timer);
      cancelAnimationFrame(this.myReq);
    },
    onMouseleave() {
      if (this.canRun()) this.reqAnimationFrame();
    },
    canRun() {
      let scrollItemBox = this.$refs.scrollItemBox;
      let scrollBox = this.$refs.scrollBox;
      let outer = this.$refs.outer;
      // 开启动画条件:滚动盒子(scrollBox)高度高于外层容器(outer)高度
      if (outer.offsetHeight >= scrollItemBox.offsetHeight) {
        this.showSecond = false;
        outer.scrollTop = 0;
        this.y = 0;
        scrollBox.style.top = 0;
        return false;
      } else {
        this.showSecond = true;
        return true;
      }
    },
    //获取dom元素的高度:content+padding+margin+border
    getComputedHeight(dom) {
      let computedStyle = getComputedStyle(dom);

      let computedHeight =
        dom.offsetHeight +
        parseFloat(computedStyle.marginTop) +
        parseFloat(computedStyle.marginBottom);
      return computedHeight;
    },
    reqAnimationFrame() {
      //外层容器
      let outer = this.$refs.outer;
      //滚动盒子
      let scrollBox = this.$refs.scrollBox;
      //滚动盒子下边的第一个scroll-item-box,
      let scrollItemBox = this.$refs.scrollItemBox;

      //滚动速度
      this.speed = this.speed > 1 ? 1 : this.speed < 0 ? 0.1 : this.speed;

      //取第一个scrollItemBox高度
      let definedHeight = this.getComputedHeight(scrollItemBox);
      //持续滚动
      this.y = this.y + this.speed;
      scrollBox.style.top = -this.y + "px";

      //====添加滚动间隔控制====开始
      if (this.singleHeight >= 20 && this.waitTime > 500) {
        if (this.controleHeight >= this.singleHeight) {
          cancelAnimationFrame(this.myReq);
          this.controleHeight = 0;
          this.timer = setTimeout(() => {
            if (this.canRun) this.reqAnimationFrame();
          }, this.waitTime);
          return;
        } else {
          // 一次移动高度未达到指定距离继续执行动画
          this.controleHeight += this.speed;
        }
      }
      //====添加滚动间隔控制====结束

      //当滚动到第一个scroll-item-box高度时scrollBox重置为top:0,视觉上是无缝滚动
      if (this.y >= definedHeight) {
        this.y = 0;
      }
      this.myReq = window.requestAnimationFrame(this.reqAnimationFrame);
    },
  },
  destroyed() {
    window.removeEventListener("resize", this.listenResizeFn);
    cancelAnimationFrame(this.myReq);
    if (this.timer) clearTimeout(this.timer);
  },
};
</script>
  <style lang="scss">
.scroll-outer {
  height: 100%;
  overflow-x: hidden;
  position: relative;
  &::-webkit-scrollbar {
    width: 0.3vw;
  }
  &:hover::-webkit-scrollbar-track {
    -webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
    border-radius: 0.1vw;
    background-color: #295099;
    opacity: 1;
    // display: none;
  }
  &:hover::-webkit-scrollbar-thumb {
    opacity: 1;
    border-radius: 0.1vw;
    -webkit-box-shadow: inset 0 0 0.1vw rgba(0, 0, 0, 0.3);
    background-color: #0ba9ea;
  }
}
.scroll-inner-box {
  height: auto;
  position: absolute;
  width: 100%;
  top: 0;
  left: 0;
}
</style>
  
  

使用示例: 

import autoScroll from "@/components/autoScroll";
<autoScroll :list="list" :speed="0.5" :waitTime="2000" :singleHeight="100">
            <div class="t-item" v-for="(item,index) in list" :key="index">
              <div class="tvalue" style="flex: 0 0 30%;">{{ item.jgjc }}</div>
              <span class="tvalue">{{ item.total||'--' }}</span>
              <span class="tvalue" style="color:#0FCBDE">{{ item.ypc||'--' }}</span>
              <span class="tvalue" style="color:#F15730">{{ item.zlz||'--' }}</span>
              <span class="tvalue" style="color:#17DB68">{{ item.zlwc||'--' }}</span>
            </div>
          </autoScroll>

使用注意:

总结 

到此这篇关于vue组件实现列表自动无限循环的文章就介绍到这了,更多相关vue列表自动无限循环内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文