vue实现局部滚动加载-加自定义滚动加载的指令

64次阅读

共计 3877 个字符,预计需要花费 10 分钟才能阅读完成。

  1. 先来实现局部的滚动加载
<template>
  <div class="cart">
    <div class="cart-musics">
      <ul class="cart-musics-ul">
        <li v-for="(item, index) in cartMusics" :key="index">
          {{item}}
        </li>
        <li class="last-page text-tblr-center" v-show="page > last_page">~没有更多了~</li>
      </ul>
    </div>
  </div>
</template>
 
<script>
export default {data () {
    return {cartMusics: ['这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据'],
      page: 1,
      last_page: 10,
      scrollBottom: null
    }
  },
  watch: {
    // 这里监听 scrollBottom 等于 0 触发获取数据的方法 否则不触发
    scrollBottom (val) {// console.log('我是 watch 监听的距离底部的距离', val)
      if (val !== 0) return false
      this.page++
      // 判断当前页数大于最后一页 return false 加载完毕
      if (this.page > this.last_page)  return false
      this.getCartMusics()}
  },
  mounted () {// this.getCartMusics()
    // 首次加载页面的时候给列表元素添加 滚动的事件监听
    document.querySelector('.cart-musics-ul').addEventListener('scroll', this.hanleScroll, true)
  },
  methods: {hanleScroll () {console.log('滚动条距离顶部的距离', document.querySelector('.cart-musics-ul').scrollTop)
      console.log('监听的元素的高度', document.querySelector('.cart-musics-ul').clientHeight)
      console.log('监听元素的滚动条的高度', document.querySelector('.cart-musics-ul').scrollHeight)
      this.scrollBottom = (document.querySelector('.cart-musics-ul').scrollHeight - document.querySelector('.cart-musics-ul').clientHeight) - document.querySelector('.cart-musics-ul').scrollTop
    },
    getCartMusics () {
      // 这里获取数据可以自行添加 loading
      // 获取数据的时候 body 超出隐藏 不会此时屏目禁止滑动
      document.body.style.overflow = 'hidden'
      this.cartMusics = this.cartMusics.concat(['这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据'])
      // 获取数据成功后设置 body overflow 为 auto
      document.body.style.overflow = 'auto'
    }
  },
  beforeDestroy () {// document.querySelector('.cart-musics-ul').removeEventListener('scroll', this.hanleScroll, true)
  }
}
</script>
 
<style lang="scss" scoped>
.cart{
  padding-top: 50px;
  font-size: 12px;
  .cart-musics{
    margin-top: 30px;
    // overflow: hidden;
    height: 500px;
    border-bottom: 1px dashed #999999;
    border-bottom-width: 2px;
    .cart-musics-ul{
      overflow-x: scroll;
      height: 500px;
      li{
        padding: 0 10px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 10px;
        height: 80px;
      }
    }
  }
}
</style>

我这的样式外层 div 的高度设置的 500 可以自行设置高度

下面把滚动加载的方法封装成 v -loadmore 自定义指令

新建 loadMore.js

import Vue from 'vue'
 
Vue.directive('loadmore', {
  // 
  inserted: (el, bind, vnode) => {
    // 这里参考管方 https://cn.vuejs.org/v2/guide/custom-directive.html#%E5%8A%A8%E6%80%81%E6%8C%87%E4%BB%A4%E5%8F%82%E6%95%B0
    // el 当前绑定的元素
    // console.log(el, bind, vnode)
    // 给元素添加滚动事件监听
    el.addEventListener('scroll', function () {console.log('绑定元素的高度:', el.clientHeight)
      console.log('绑定元素的滚动条的高度', el.scrollHeight)
      console.log('滚动条距离顶部的距离', el.scrollTop)
      console.log('滚动条的高度 - 元素的高度 - 滚动条距离顶部的距离 = 0', (el.scrollHeight - el.clientHeight) - el.scrollTop)
       // 这里的判断和上面 watch 监听是一样的
      if ((el.scrollHeight - el.clientHeight) - el.scrollTop === 0) {
        // binding.value 来调用指令上的方法获取数据
        binding.value()}
    })
  }
})

页面中使用就简单很多了 可以直接使用指令绑定一个方法来调用获取数据的方法

<template>
  <div class="cart">
    <div class="cart-musics">
      <ul class="cart-musics-ul" v-loadmore="loadMore">
        <li v-for="(item, index) in cartMusics" :key="index">
          {{item}}
        </li>
        <li class="last-page text-tblr-center" v-show="page > last_page">~没有更多了~</li>
      </ul>
    </div>
  </div>
</template>
 
<script>
export default {data () {
    return {cartMusics: ['这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据'],
      page: 1,
      last_page: 10,
      scrollBottom: null
    }
  },
  mounted () {},
  methods: {
    // 指令的方式直接调用指令上的方法
    loadMore () {
      this.page++
      // 判断当前页数大于最后一页 return false 加载完毕
      if (this.page > this.last_page)  return false
      this.getCartMusics()},
    getCartMusics () {
      // 这里获取数据可以自行添加 loading
      // 获取数据的时候 body 超出隐藏 不会此时屏目禁止滑动
      document.body.style.overflow = 'hidden'
      this.cartMusics = this.cartMusics.concat(['这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据', '这是测试的数据'])
      // 获取数据成功后设置 body overflow 为 auto
      document.body.style.overflow = 'auto'
    }
  }
}
</script>
 
<style lang="scss" scoped>
.cart{
  padding-top: 50px;
  font-size: 12px;
  .cart-musics{
    margin-top: 30px;
    // overflow: hidden;
    height: 500px;
    border-bottom: 1px dashed #999999;
    border-bottom-width: 2px;
    .cart-musics-ul{
      overflow-x: scroll;
      height: 500px;
      li{
        padding: 0 10px;
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 10px;
        height: 80px;
      }
    }
  }
}
</style>

自己实现滚动加载就是这样的

知识积累,有不足的地方希望各位评论中指出来改进

正文完
 0