vue——实现数据懒加载(可视区域内才进行数据加载)——技能提升

昨天部门会议,领导提出一个需求,就是当一个前端页面有上百个图表或者其它元素,对应的接口有许多时,为了体验效果,不能一次性加载全部的数据,只有当元素滚动到可视区域内时,再进行相应接口的调用,也就是数据的懒加载。

如下图所示:目前出现在可视区域内部的只有图表0 图表1 图表2 图表34个元素,控制台也能拿到对应的索引或者dom元素。
在这里插入图片描述

当滚动页面出现图表4 图表5出现在可视区域时,控制台也能拿到对应的索引或者dom元素
在这里插入图片描述

而且页面回滚的时候,不会再次请求接口。

能拿到当前可视区域展示的dom元素,就可以获取对应的接口数据了。

下面介绍实现方法:

1.在main.js中添加自定义指令

Vue.directive('lazy', {
    
    
    bind: function (el, binding) {
    
    
        let lazyLoadObser = new IntersectionObserver((entries, observer) => {
    
    
            entries.forEach((entry, index) => {
    
    
                let lazyImage = entry.target
                if (entry.intersectionRatio > 0) {
    
    
                    binding.value.throttle(binding.value.getData,200)(binding.value.id, lazyLoadObser, lazyImage)
                }
            })
        })
        lazyLoadObser.observe(el)
    }
})

2.页面上使用指令——以图片懒加载为例

html部分:

<div class="kjWrap">
  <div class="kj" v-for="(item, index) in originData" :key="index">
    <img v-lazy="{ getData: getData, id: item.id, throttle: throttle }" :src="item.img"/>
  </div>
</div>

样式部分:

<style lang="less" scoped>
.kjWrap {
    
    
  display: flex;
  flex-wrap: wrap;
  .kj {
    
    
    width: 50%;
    height: 200px;
    border: 1px solid red;
    img {
    
    
      width: 100%;
      height: 100%;
      object-fit:cover;
    }
  }
}
</style>

script部分:

data(){
    
    
	return{
    
    
		originData: [
        {
    
    id: 0},
        {
    
    id: 1},
        {
    
    id: 2},
        {
    
    id: 3},
        {
    
    id: 4},
        {
    
    id: 5},
        {
    
    id: 6},
        {
    
    id: 7},
        {
    
    id: 8},
        {
    
    id: 9},
      ],
	}
}
methods:{
    
    
	// 闭包节流
    throttle(fn, wait) {
    
    
      let timer = '';
      return function(...args) {
    
    
        if (timer) return;
        timer = setTimeout(() => {
    
    
          timer = null;
          fn.apply(this, args);
        }, wait);
      };
    },
    getData(id, lazyLoadObser, lazyImage) {
    
    
      console.log('开始加载数据了', id, lazyLoadObser, lazyImage);
      // 解绑监听事件
      lazyLoadObser.unobserve(lazyImage);
      let list = [
        'https://img2.baidu.com/it/u=2632350353,4292959661&fm=253&fmt=auto&app=138&f=JPEG?w=819&h=500',
        'https://img2.baidu.com/it/u=2632350353,4292959661&fm=253&fmt=auto&app=138&f=JPEG?w=819&h=500',
        'https://img1.baidu.com/it/u=147161764,3142008484&fm=253&fmt=auto&app=120&f=JPEG?w=654&h=368',
        'https://img1.baidu.com/it/u=147161764,3142008484&fm=253&fmt=auto&app=120&f=JPEG?w=654&h=368',
        'https://img1.baidu.com/it/u=147161764,3142008484&fm=253&fmt=auto&app=120&f=JPEG?w=654&h=368',
        'https://img1.baidu.com/it/u=147161764,3142008484&fm=253&fmt=auto&app=120&f=JPEG?w=654&h=368',
        'https://img0.baidu.com/it/u=3419722502,755567528&fm=253&fmt=auto&app=138&f=JPEG?w=1000&h=500',
        'https://img0.baidu.com/it/u=3419722502,755567528&fm=253&fmt=auto&app=138&f=JPEG?w=1000&h=500',
        'https://img0.baidu.com/it/u=3419722502,755567528&fm=253&fmt=auto&app=138&f=JPEG?w=1000&h=500',
        'https://img0.baidu.com/it/u=3419722502,755567528&fm=253&fmt=auto&app=138&f=JPEG?w=1000&h=500',
        'https://img0.baidu.com/it/u=3419722502,755567528&fm=253&fmt=auto&app=138&f=JPEG?w=1000&h=500',
      ];
      this.$set(this.originData[id], 'img', list[id]);
    },
}

完成!!!

如果不是图片,而是其它元素,也可以通过此方法实现,只需要将html中的img部分更换掉,script中的getData方法中添加对应的接口调用即可。

多多积累,多多收获!!!

猜你喜欢

转载自blog.csdn.net/yehaocheng520/article/details/130981910