Vue3懒加载指令实现

封装全局指令

// 定义懒加载插件,当前文件路径src/directives/index.js
import { useIntersectionObserver } from '@vueuse/core'

export const lazyPlugin = {
  install (app) {
    // 懒加载指令逻辑
    app.directive('img-lazy', {
      mounted (el, binding) {
        // el: 指令绑定的那个元素 img
        // binding: binding.value  指令等于号后面绑定的表达式的值  图片url
        console.log(el, binding.value)
        const { stop } = useIntersectionObserver(
          el,
          ([{ isIntersecting }]) => {
            console.log(isIntersecting)
            if (isIntersecting) {
              // 进入视口区域
              el.src = binding.value
              //如果不想在图片资源懒加载完成后依然对其进行监听,则需要添加stop()方法
              stop()
            }
          },
        )
      }
    })
  }
}

注册全局指令

// main.js文件内全局指令注册
import { directivePlugin } from '@/directives'
app.use(directivePlugin)

使用

<RouterLink to="/">
  <img v-img-lazy="imgUrl" alt="">
</RouterLink>

useIntersectionObserver方法原理

IntersectionObserver是一个用于识别当前目标元素与另一个元素(该另一元素是视口或元素)相交情况的API。通过判断元素与视口是否有交叉来替代监听滚动事件处理懒加载。因此它不需要监听滚动事件,可以让页面更加流畅。

使用IntersectionObserver需要创建一个实例,把待监听的元素传入其中,并定义一个回调函数(即为目标元素与视口或元素相交时被调用的函数)。当目标元素出现在视口中或与监视器容器相交时,回调函数将被调用。

<!-- 图片标签,添加 data-src 属性表示要进行懒加载的图片 -->
<img class="lazyload" data-src="image.png">
// 查询所有待懒加载的元素
const lazyImages = document.querySelectorAll('.lazyload');

// 配置项
let options = {
  root: null,
  rootMargin: '0px',
  threshold: 0.1
};

// 回调函数
function handleIntersection(entries) {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      observer.unobserve(img);
    }
  });
}

// 创建 IntersectionObserver 实例
const observer = new IntersectionObserver(handleIntersection, options);

// 监听每个待懒加载的图片元素
lazyImages.forEach(img => {
  observer.observe(img);
});

上述代码中,我们首先查询所有待懒加载的图片元素,并定义一个 IntersectionObserver 实例 observer。当目标元素出现在视口中或与监视器容器相交时,回调函数 handleIntersection 将被调用,并通过将 data-src 属性复制到 src 属性来完成懒加载,并最终解除对该图片元素的监听。

注意:创建实例后需要使用 observe() 方法将需要被监听的元素传递给它,可以一次性地监听多个元素。另外,如果没有任何图片元素需要被监听了,还需要使用 unobserve() 方法取消观察。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值