17、列表上下定时滚动

105 阅读1分钟

1、封装滚动组件

<template>
  <div class="dh-autoscorll" :style="styles">
    <div v-for="item in scorllDatas" :key="item.id">      
      <slot v-bind:scorllItem="item"></slot>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    datas: {
      type: Array,
      default: () => [],
    },
    speed: {
      type: Number,
      default: 3,
    },
    type: {
      type: Number,
      default: 1, // 1 竖向滚动; 2 横向滚动
    },
    // 几个可见数据
    showNum: {
      type: Number,
      default: 2,
    },
  },
  computed: {
    styles() {
      let style = {};
      if (this.isNeedAnimotion) {
        style.transition = `top ${this.speed}s linear`;
      }
      if (this.type === 1) {
        // style["transform"] = `translate(0, -${this.currentScorllHeight}px)`;
        style["top"] = `-${this.currentScorllHeight}px`;
      } else {
        style["transform"] = `translate(-${this.currentScorllHeight}px, 0)`;
      }
      return style;
    },
  },
  watch: {
    datas(value, oldValue) {
      if (oldValue.length <= this.showNum || value.length <= this.showNum) {
        this.allDatas = value;
        this.initScollData();
        return;
      }
      if (value.length === 0) {
        this.allDatas = [];
        this.scorllDatas = [];
      } else {
        if (value[0].id === oldValue[0].id && value.length === oldValue.length)
          return;
        this.allDatas = value;
      }
      this.currentIndex = 0;
      this.startScoll();
    },
    allDatas() {
      this.startScoll();
    },
  },
  data() {
    return {
      currentIndex: 0,
      scorllDatas: [], // 滚动数据
      currentScorllHeight: 0,
      isNeedAnimotion: true,
    };
  },
  created() {
    this.allDatas = [...this.datas]; // 缓存所有数据
    this.initScollData();
    this.currentScorllHeight = 0;
  },
  mounted() {
    this.calculateScorllHeight();
  },
  methods: {
    initScollData() {
      this.isNeedAnimotion = false;
      this.currentScorllHeight = 0;
      if (this.allDatas.length > this.showNum) {
        this.scorllDatas = this.allDatas.slice(0, this.showNum + 1);
        this.currentIndex = this.showNum + 1;
      } else {
        this.scorllDatas = [...this.allDatas];
      }
      this.startScoll();
    },
    startScoll() {
      if (this.allDatas.length > this.showNum) {
        if (!this.intv) {
          this.$nextTick(() => {
            this.calculateScorllHeight();
          });
          this.intv = setInterval(() => {
            this.scorll();
          }, this.speed * 1000);
        }
      } else {
        this.intv && clearInterval(this.intv);
        this.intv = null;
      }
    },
    addDatas(data) {
      this.allDatas.unshift(data);
      this.currentIndex++;
      this.scorllDatas.push(data);
    },
    scorll() {
      if (this.height === 0) return;
      if (this.currentScorllHeight > 0) {
        this.scorllDatas.shift();
        this.currentScorllHeight = 0;
        this.isNeedAnimotion = false;
      } else {
        this.currentScorllHeight = this.height;
        this.isNeedAnimotion = true;
      }
      if (this.scorllDatas.length < this.showNum + 1) {
        if (this.currentIndex === this.allDatas.length) {
          this.currentIndex = 0;
        }
        this.scorllDatas.push(this.allDatas[this.currentIndex]);
        this.currentIndex++;
      }
    },
    calculateScorllHeight() {
      let el = this.$el.firstElementChild;
      this.height = 0;
      if (el) {
        el.get;
        this.height =
          this.type === 1
            ? el.getClientRects()[0].height
            : el.getClientRects()[0].width;
      } else {
        this.height = 0;
      }
    },
  },
};
</script>
<style lang="less" scoped>
.dh-autoscorll {
  //   will-change: transform;
  position: absolute;
  *,
  ::after,
  ::before {
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
  }
  & > div {
    border: 0.5px solid rgba(0, 0, 0, 0); // 为了获取子元素margin
  }
}
</style>

2、使用组件-赋值