vue页面滚动加载、页面懒加载

 需求:页面有一堆图表、需要滚动到图表时、再加载出来这个图表、

思路:没找到合适的插件、只能自己手撸一个、直接放到混入里就行、主要就是判断元素距离底部的距离和可视区域内容的高度进行对比即可

/**
 * 判断某个原生DOM元素是否已经在屏幕可见区内出现过
 * @param {*} el 原生DOM元素
 */
const isElementNotInViewport = function (el) {
  let rect = el.getBoundingClientRect();
  return rect.bottom <= (window.innerHeight || document.documentElement.clientHeight)
};

export { isElementNotInViewport };

注意、这个方法是判断内容已经出现在可视区域、也可能划上去了、所以是出现过、只需要判断元素底部的距离小于可视区域内容的高度即可、如果只需要判断可视区域、那么就需要加上元素距离顶部的距离top

混入中的完整代码 mixins.js

import { isElementNotInViewport } from "libs/public.js";

export default {
  data() {
    return {
      isLoading: false,
      oldScrollTop: 0, //记录上一次滚动结束后的滚动距离
      scrollTop: 0, // 记录当前的滚动距离
    }
  },
  mounted() {
    // 图表懒加载
    this.$nextTick(() => {
      let timer;
      const that = this;
      const valuePage = document.getElementById("id名称");
      valuePage .addEventListener("scroll", (e) => {
        this.scrollTop = valuePage .scrollTop;
        // 判断是否向下滚动
        if (this.scrollTop - this.oldScrollTop > 0) {
          for (let k = 1; k <= this.echartsNum; k++) {
            if (!this[`show${k}`]) {
              this.isLoading = true;
            }
          }
          if (timer) {
            clearTimeout(timer);
          }
          timer = setTimeout(() => {
            that.handleScroll();
          }, 200);
        }
      });
      this.handleScroll();
    });
  },
  watch: {
    scrollTop(newValue, oldValue) {
      const valuePage = document.getElementById("id名称");
      setTimeout(() => {
        if (newValue === valuePage .scrollTop) {
          // 滚动结束
          setTimeout(() => {
            this.isLoading = false;
          }, 1000);
          this.oldScrollTop = newValue; //每次滚动结束后都要给oldScrollTop赋值
        }
      }, 20); //必须使用延时器,否则每次newValue和滚动条scrollY都相等,无法判断,20ms刚好大于watch的侦听周期,故延时20ms
      if (this.oldScrollTop == oldValue) {
        //滚动开始 oldScrollTop与oldValue相等
      }
    },
  },
  methods: {
    handleScroll() {
      for (let k = 1; k <= this.echartsNum; k++) {
        let viewDom = document.getElementById(`show${k}`);
        if (isElementNotInViewport(viewDom)) {
          this[`show${k}`] = true;
        }
      }
    }
  }
}

页面使用

<template>
<div>
    <Card id="show1">
        <div v-if="show1">        
             内容1234567890
        </div>
    </Card>
    <Card id="show2">
        <div v-if="show2">        
             内容1234567890
        </div>
    </Card>
    <Card id="show3">
        <div v-if="show3">        
             内容1234567890
        </div>
    </Card>
    ......................
</div>
</template>

<script>
import mixin from "libs/mixins";
export default {
  mixins: [mixin],
  data() {
    return {
          show1: false,
          show2: false,
          show3: false,
          echartsNum: 3, //  需要滚动加载的图表数量 
       }
    }
 }
</script>

这里使用了id 、没用ref的原因是报错了、排查半天没找到原因、哈哈哈!

写的一般、欢迎大佬们指正!

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值