v-lazy自定义指令实现图片懒加载

这次我在项目中遇到同时加载多张图片,带宽瞬间大量消耗,造成页面卡顿。给图片懒加载,避开带宽峰值,提高页面加载速度。

封装懒加载使用到IntersectionObserver API

IntersectionObserver API提供了一种异步观察目标元素与其祖先元素或顶级文档视口(viewport)交叉状态的方法。其祖先元素或视口被称为根(root)。

const observer = new IntersectionObserver(callback, {
  root: null, // 默认以视口为观察容器
  rootMargin: '200px', // 计算交叉时添加到根边界盒的矩形偏移量,提前200px触发加载
  threshold: 0.01 // 元素可见1%即触发
});

关于自定义指令

自定义指令主要是为了重用涉及普通元素的底层 DOM 访问的逻辑。一个自定义指令由一个包含类似组件生命周期钩子的对象来定义。钩子函数会接收到指令所绑定元素作为其参数。

自定义指令的注册方式

局部注册,需要通过directives 选项注册
 

export default {
  directives: {
    // 在模板中启用 v-lazy
    lazy: {
      /* ... */
    }
  }
}

自定义组件的全局注册

Vue.directive('lazy',lazyLoad)

关于指令钩子
 

export default {
  //首次绑定到元素时触发(适合初始化操作)
  bind(el, binding) {},
  
  //  元素插入父节点时触发(适合DOM相关操作)
  inserted(el, binding) {},

  // 所在组件VNode更新时触发
  update(el, binding) {
    // 当绑定值变化时会触发
    if (binding.oldValue !== binding.value) {
      // 可在此添加重新加载逻辑
    }
  },

  // 所在组件及子组件VNode更新后
  componentUpdated(el, binding) {
    // 可用于处理子组件更新后的操作
  },

  //指令解绑时触发
  unbind(el) {
    // 应在此清理IntersectionObserver
    // observer.disconnect()
  }
}

指令钩子中使用的参数

el:指令绑定到的元素。这可以用于直接操作 DOM。
binding:一个对象,包含以下属性:
value:传递给指令的值。
instance:使用该指令的组件实例。

了解完前置知识,现在创建lazy.js文件,存放自定义指令

export default {
  inserted(el, binding) {
    
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
       //访问组件实例
        if (entry.isIntersecting) {
          const img = new Image()
          img.src = binding.value
          img.onload = () => {
            el.src = binding.value
            el.classList.add('fade-in')
          }
          img.onerror = () => {
            el.src = require('@/assets/error-img.png')
          }
          // 停止监听特定目标元素
          observer.unobserve(el)
        }
      })
    })
   // 开始监听一个目标元素
    observer.observe(el)
  }
}

把懒加载自定义组件放全局,在main.js中注册

import lazyLoad from '@/directives/lazy.js' 
Vue.directive('lazy',lazyLoad)

最后给图片使用 v-lazy指令

 <img
     v-lazy="imgSrc"
     src="放base64图" />

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值