2.Vue 图片懒加载指令

1.什么是图片懒加载

当一个组件或者是一个页面存在着大量的img标签,需要加载大量的图片,如果不使用懒加载处理图片,那么将在页面出现或者组件挂载的时候一次性加载完毕所有的图片,非常消耗性能,还有可能造成白屏时间过长,影响用户的体验感。那么经过懒加载处理的图片,只有当图片进入视口区域时,图片才会加载,避免了性能的浪费。

2.懒加载指令

Vue3写法,需要用到Vueuse函数库,非常方便,记得提前下载

//定义懒加载模块
import { useIntersectionObserver } from '@vueuse/core'

export const lazyPlugin = {
    install(app){
        app.directive('img-lazy',{
            //el:指令绑定的元素
            //binding:表达式的值
            mounted(el,binding){
               const {stop} = useIntersectionObserver(
                    el,
                    ([{ isIntersecting }]) => {
                        if(isIntersecting){
                            //进入视口区域
                            el.src = binding.value
                            stop()
                        }
                    },
                  )
            }
        })
    }
}

记得提前组件内引入或者全局注册,组件内使用

<img v-img-lazy="item.url">

第二种写法Vue2

// 图片懒加载
export const LazyLoad = {
  install (Vue, options) {
    // 代替图片的loading图
    options = options || {}
    const defaultSrc = require('../assets/loading.gif')
    const Lazy = Vue.directive('lazy', {
      bind (el, binding) {
        LazyLoad.init(el, binding.value, defaultSrc)
      },
      inserted (el) {
        // 兼容处理
        if ('IntersectionObserver' in window) {
          LazyLoad.observe(el)
        } else {
          LazyLoad.listenerScroll(el)
        }
      }
    })
    return Lazy
  },

  // 初始化
  init (el, val, def) {
    // data-src 储存真是src
    el.setAttribute('data-src', val)
    // 设置src为loading图
    el.setAttribute('src', def)
  },

  // 利用IntersectionObserver监听el
  observe (el) {
    const io = new IntersectionObserver(entries => {
      const readSrc = el.dataset.src
      // 如果进入视口
      if (entries[0].isIntersecting) {
        if (readSrc) {
          el.src = readSrc
          el.removeAttribute('data-src')
        }
      }
    })
    io.observe(el)
  },

  // 监听scroll事件
  listenerScroll (el) {
    const handler = LazyLoad.throttle(LazyLoad.load, 300)
    LazyLoad.load(el)
    window.addEventListener('scroll', () => {
      handler(el)
    })
  },

  // 加载真实图片
  load (el) {
    const windowHeight = document.documentElement.clientHeight
    const elTop = el.getBoundingClientRect().top
    const elBtm = el.getBoundingClientRect().bottom
    const realSrc = el.dataset.src
    if (elTop - windowHeight < 0 && elBtm > 0) {
      if (realSrc) {
        el.src = realSrc
        el.removeAttribute('data-src')
      }
    }
  },

  // 节流的时间戳写法
  throttle (fn, delay) {
    let timer
    let prevTime
    return function (...args) {
      const currTime = Date.now()
      const context = this
      if (!prevTime) prevTime = currTime
      clearTimeout(timer)

      if (currTime - prevTime > delay) {
        prevTime = currTime
        fn.apply(context, args)
        clearTimeout(timer)
        return
      }

      timer = setTimeout(function () {
        prevTime = Date.now()
        timer = null
        fn.apply(context, args)
      }, delay)
    }
  }
}

注册

import { throttle, debounce, LazyLoad } from './directive'

Vue.use(LazyLoad.install(Vue))

图片引入Vue2要使用require,否则直接写路径会报错

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值