• vue3 组合式api 实现v-lazy 图片懒加载


    前置知识

    Intersection Observer

    浏览器提供api,用于检测目标元素和祖先元素/顶级文档视窗 (viewport) 交叉状态的方法。

        const observer = new IntersectionObserver(function (IntersectionObserverEntry) {},options);
        observer.observe(el);
    

    构造函数接收一个回调函数,一个配置对象(可选),返回一个观察器实例。实例的observe方法接收一个dom节点作为观察的对象
    当目标对象出现在视口的时候,会调用回调函数,传递一个元素都为IntersectionObserverEntry对象的数组。
    IntersectionObserverEntry对象有以下属性 (只列举了这篇用到的两个):

    • target:被观察的目标元素,是一个 DOM 节点对象
    • intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0

    Vue3指令周期

    • created:在绑定元素的 attribute 或事件监听器被应用之前调用;

    • beforeMount:当指令第一次绑定到元素并且在挂载父组件之前调用;

    • mounted:在绑定元素的父组件被挂载后调用;

    • beforeUpdate:在更新包含组件的 VNode 之前调用;

    • updated:在包含组件的 VNode 及其子组件的 VNode 更新后调用;

    • beforeUnmount:在卸载绑定元素的父组件之前调用;

    • unmounted:当指令与元素解除绑定且父组件已卸载时,只调用一次;

    image对象

    Image 对象代表嵌入的图像。

    • onload 当图像装载完毕时调用的回调函数。

    思路

    • 想要的效果 在有多个图片加载的时候 只要在最外面的wrapper上用一次v-lazy就可以
    • 每张图片的src先用加载gif替换掉,然后再放到文档碎片里面,等到用户滑动到视口了再挂载上图片元素,之前一直使用加载的gif占位,等图片加载完成再替换。
       首先vue3的指令跟组件类似也有生命周期,created的时候指令绑定的dom元素还没有attribute,也没有DOM结构,所以不适合,mounted整个DOM元素已经挂载到页面上了,图片在挂载上去的时候就开始加载,再做懒加载已经没有意义了,所以使用beforeMount,有完整的DOM结构,但是没有挂载到页面上。

    完整代码

    export const lazyLoad = {
      beforeMount(el: any, binding: any, vnode: any, prevVnode: any) {
        const img = el.querySelector(`.${el.className} img`);
        const src = img.getAttribute("src");
        // 图片使用loading gif替换
        img.setAttribute("src", "https://m.tea7.com/images/imgLoading.gif");
        // 新建Image对象
        const tempImg = new Image();
        tempImg.onload = function () {
          img.setAttribute("src", src);
        };
        const parent = img.parentNode;
        const observer = new IntersectionObserver(function (changes) {
          // 可视
          changes.forEach((item) => {
            if (item.intersectionRatio !== 0) {
              tempImg.src = src;
            }
          });
        });
        observer.observe(el);
      },
    };
    
    

    参考链接:
    IntersectionObserver API 使用教程

  • 相关阅读:
    安卓JNI怎么使用lua库呢,为何这样不行呢
    FFmpeg源代码简单分析-编码-日志输出系统(av_log()等)
    什么是超融合?与传统架构有什么区别?.
    MySQL存储引擎
    一文读懂:testcafe框架和页面元素交互
    Stable Diffusion的入门介绍和使用教程
    Leetcode5:最长回文子串(待学习)
    【FOC】FOC控制流程图
    后台管理弹出框样式设置
    多平台的免费chatGPT应用软件平台推荐:Chatbox
  • 原文地址:https://blog.csdn.net/neversleepy/article/details/127020065