用vue自定义指令实现图片懒加载:

功能实现的核心思维:

  • 我是用的IntersectionObserver API去实现的;
  • IntersectionObserver 对象的observe() 方法向IntersectionObserver对象监听的目标集合添加一个元素。一个监听者有一组阈值和一个根, 但是可以监视多个目标元素,以查看这些目标元素可见区域的变化;

链接地址: IntersectionObserver API

封装的图片懒加载的核心代码;

// 这个是引入的一张logon图片
import img from "@/assets/logo.png";
let timer = null; // 创建一个监听器
let observer = new IntersectionObserver((entries) => {
  // entries是所有被监听对象的集合
  entries.forEach((entry) => {
    if (entry.isIntersecting || entry.intersectionRatio > 0) {
      // 当被监听元素到临界值且未加载图片时触发。
      !entry.target.isLoaded && showImage(entry.target, entry.target.data_src);
    }
  });
});
function showImage(el, imgSrc) {
  const img = new Image();
  img.src = imgSrc;
  img.onload = () => {
    el.src = imgSrc;
    el.isLoaded = true;
  };
}
export default {
  // 这里用inserted和bind都行,因为IntersectionObserver时异步的,以防意外还是用inserted好一点  // inserted和bind的区别在于inserted时元素已经插入页面,能够直接获取到dom元素的位置信息。
  inserted(el, binding, vnode) {
    clearTimeout(timer); // 初始化时展示默认图片
    el.src = img; // 将需要加载的图片地址绑定在dom上
    el.data_src = binding.value;
    observer.observe(el);
    // 防抖,这里在组件卸载的时候停止监听
    const vm = vnode.context;
    timer = setTimeout(() => {
      vm.$on("hook:beforeDestroy", () => {
        observer.disconnect();
      });
    }, 20);
  }, // 图片更新触发
  update(el, binding) {
    el.isLoaded = false;
    el.data_src = binding.value;
  },
  /**
   *  unbind不太好,会执行多次,改进一下用组件的beforeDestroy卸载
   *  unbind(){
   *   // 停止监听
   *   observer.disconnect();
   *  }}
   **/
};

需要在man.js 入口文件全局注册自定义指令;

// 引入全局指令的核心代码的路径;
import image from "./utils/directive/image";
Vue.directive("image", image);

在组件中使用使用自定义指令;

<template>
  <div>
    <div v-for="(item, index) in imgSrc" :key="index">
      <img v-image="item" />
    </div>
  </div>
</template>

<script>
import image from "@/utils/directive/image.js";
export default {
  directives: {
    image: image,
  },
  data() {
    return {
      imgSrc: [
        "http://img10.360buyimg.com/da/s1180x940_jfs/t1/140815/14/928/75404/5eea125aE80867bc3/540b8da207f399ca.jpg",
        "http://img14.360buyimg.com/mobilecms/s280x280_jfs/t1/112324/19/2435/79507/5ea24977E08f79bb6/f2a77cbd1c74549c.jpg",
        "http://img10.360buyimg.com/img/jfs/t1/117726/20/7368/88789/5ec3777cE70ffaf64/47d8f5d0310958bd.gif",
        "http://img11.360buyimg.com/jdcms/s300x300_jfs/t1/127115/26/5040/311434/5eea32ffEee00881f/17dfa7f424bed8a0.jpg",
        "http://img20.360buyimg.com/jdcms/s300x300_jfs/t1/56673/16/10608/172980/5d79e30dEb869e5b4/ebf71584c27d9a42.jpg",
        "http://img10.360buyimg.com/da/s1180x940_jfs/t1/140815/14/928/75404/5eea125aE80867bc3/540b8da207f399ca.jpg",
        "http://img14.360buyimg.com/mobilecms/s280x280_jfs/t1/112324/19/2435/79507/5ea24977E08f79bb6/f2a77cbd1c74549c.jpg",
        "http://img10.360buyimg.com/img/jfs/t1/117726/20/7368/88789/5ec3777cE70ffaf64/47d8f5d0310958bd.gif",
        "http://img11.360buyimg.com/jdcms/s300x300_jfs/t1/127115/26/5040/311434/5eea32ffEee00881f/17dfa7f424bed8a0.jpg",
        "http://img20.360buyimg.com/jdcms/s300x300_jfs/t1/56673/16/10608/172980/5d79e30dEb869e5b4/ebf71584c27d9a42.jpg",
        "http://img10.360buyimg.com/da/s1180x940_jfs/t1/140815/14/928/75404/5eea125aE80867bc3/540b8da207f399ca.jpg",
        "http://img14.360buyimg.com/mobilecms/s280x280_jfs/t1/112324/19/2435/79507/5ea24977E08f79bb6/f2a77cbd1c74549c.jpg",
        "http://img10.360buyimg.com/img/jfs/t1/117726/20/7368/88789/5ec3777cE70ffaf64/47d8f5d0310958bd.gif",
        "http://img11.360buyimg.com/jdcms/s300x300_jfs/t1/127115/26/5040/311434/5eea32ffEee00881f/17dfa7f424bed8a0.jpg",
        "http://img20.360buyimg.com/jdcms/s300x300_jfs/t1/56673/16/10608/172980/5d79e30dEb869e5b4/ebf71584c27d9a42.jpg",
      ],
    };
  },
};
</script>

<style scoped>
img {
  width: 500px;
  height: 500px;
}
</style>

效果演示:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柚子·小哥哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值