实现vueSeamlessScroll插件无缝滚动以及翻页

解决思路:

vueSeamlessScroll 滚动是因为盒子translate 在匀速改变,我需要的效果是往上滚动,所以translateY在递减,鼠标移入暂停滚动。那么首先需要动态拿到translateY的值。

vueSeamlessScroll 复制了一份我的盒子,实现无缝滚动。那么当我的数据 translateY(每一条高度是45px)为 > 45 就可以请求下一条数据,但是不能直接替换(因为还没有展示完),就用js将插件复制的盒子的 innerHTML改成我需要展示的下一条数据即可。

且每次请求的数据条数需要大于页面显示条数,如果少于页面显示条数,则push进数组,然后滚动到底部,回到第一页请求时,再进行替换,循环往复

当完全滚动完成之后(translateY会归零),将数据替换掉,这样从视觉上来说,是不会出现数据改变的情况的

准备工作:

安装:

npm install vue-seamless-scroll --save  

引入: 

<script>
import vueSeamlessScroll from 'vue-seamless-scroll'  // vue2 引入插件

export default {
components: {
    vueSeamlessScroll,
  },
// 配置数据
  computed: {
    classOption() {
      return {
        step: 0.8, // 数值越大速度滚动越快
        limitMoveNum: 6, // 开始无缝滚动的数据量 this.dataList.length
        hoverStop: true, // 是否开启鼠标悬停stop
        direction: 1, // 0向下 1向上 2向左 3向右
        openWatch: true, // 开启数据实时监控刷新dom
        singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1
        singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3
        waitTime: 1000, // 单步运动停时间
      }
    }
  },
data(){
return{
 getOne: true,
}
</script>

html部分:

  <vue-seamless-scroll :data="realnum" class="table-warp" ref="seamlessScroll" :class-option="classOption" @ScrollEnd="ScrollEnd">
            <ul class="table-item">
              <li v-for="(item) in realnum" :key="item.id">
                <p>{{item.endTime}}</p>
                <p>{{item.itemText}}</p>
                <p>{{item.object}}</p>
                <p>{{item.useTime}}</p>
                <p>{{item.online?'是':'否'}}</p>
              </li>
            </ul>
  </vue-seamless-scroll>

// realnum 是请求回来的数据

写一个计时器,动态拿到translate数值(这里需要一个变量控制,避免多开定时器)

// 计时器  
getHeightTime() {
      this.runHeight = document.querySelector('.table-warp').children[0];  // 滚动的元素 table-warp是自定义的类名
      this.timer = setInterval(() => {
        this.str = this.runHeight.style.transform.substr(16);
        this.str = this.str.substr(0, this.str.length - 3).split('.')[0] * 1 // 只需要数值部分
      }, 50);
    },

this.str  即为拿到的 translateY 的数值,,监听它的变化:

 watch: {
    str(newval) {
// 45 我的每一行高度为45 可以自己定义其它数值
      if (newval >= 45 && this.getOne) {
        this.getMore() // 分页请求数据
        this.getOne = false  // 避免计时请求重复 (因为不能特别准确的拿到str)
        clearInterval(this.timer) // 清除定时器
      }

    },

下面是分页请求数据的方法(改变current)

盒子中展示的滚动数据条数是6条,所以当小于6条时需要特殊处理

 getMore() {
      let pageTotal = Math.ceil(this.realnumLength / 10) // 最大页数
      if (this.current < pageTotal) {
        // 现有总数小于所有总数
        this.current++
      } else if (this.current == pageTotal) {
        this.current = 1
      }
        this.getdata() // 请求数据
    },

getdata(){
 this.$api.service.getdataRecord({ size: 10, current: this.current }).then(res => {
          this.realnumLength = res.data.total // 数据总数
          let list = res.data.records  // 数据列表
          if (this.firstGet) {  // 第一次请求 
            this.realnum = res.data.records  // this.realnum 放到插件中的数据
            if (this.realnumLength > 10) { // 超过10条 即有第二页
              this.getHeightTime(); // 开启定时器
            }
            this.firstGet = false; //this.firstGet 控制第一次请求数据赋值方式
          } else {
            if (list.length >= 6) { // 该次请求数据条数 超过6条改变插件复制的盒子的innerHTML 这里我直接写类名无效(百度说innerHTML 上的类名是没有效果的,appendChild然后追加类名才行,但是这里要append的元素太多了),所以样式都写在style里面的
              let runHeight = document.querySelector('.table-warp').children[0].children[1].children[0];
              this.realnumData = res.data.records  //this.realnumData 暂存本次请求的数据
              let str = ''
              this.realnumData.forEach(item => {
                str += `<li style = 'height:40px; display: flex;justify-content: space-between;align-items: center; padding: 0 14px; margin-bottom: 5px; background: rgba(5, 98, 217, 0.2); font-size: 14px;font-weight: 400;color: #ecf7ff;'><p style ='width: 28%;'>${item.endTime}</p> <p  style ='width: 25%;'>${item.itemText}</p> <p  style ='width: 25%;'>${item.object}</p><p  style ='width: 10%;'>${item.useTime}</p><p style ='width: 12%;text-align: center;color: rgba(240, 201, 43, 1);'>${item.online ? '是' : '否'}</p></li> `
              })
              runHeight.innerHTML = str  // 这样当第一条数据滚动到顶部时,展示的就是第二条数据
            } else {
              // 下一页小于6条 因为设置了6条开始滚动
              this.realnumData = []
              this.realnum.push(...list)  
              this.$refs.seamlessScroll.reset() // 更新数据
              // 此处一定是最后一页,所以不需要重新计时
            }
          }
        }).catch(e => {
          console.log(e, 'error');
        })
}

利用插件的滚动回调事件(数据滚动完成触发)translateY=盒子高度:

 // 滚动完成
    ScrollEnd() {
      if (this.realnumData.length != 0) {
        this.realnum = this.realnumData   // 将数据更新 this.realnumData 之前暂存的数据
      }
      this.getOne = true  // 避免重开计时器
      this.getHeightTime(); // 计算实时办件滚动请求
    },

Logo

前往低代码交流专区

更多推荐