Vue中网络图片懒加载工具

发布时间 2023-11-10 17:50:13作者: 不停奔跑的蜗牛

在滑动列表视图中如果有网络图片需要加载直接给imag标签赋值src,会造成没有显示的item中图片也直接加载,势必浪费网络资源。

创建一个插件,让列表中的item出显的时候在加载图片从而减少网络请求。具体方法就是给img标签添加一个新的属性暂时先保存对应的url,当item滑动出现到一定值时触发事件再吧url赋值给image标签

具体代码:

import type { App, DirectiveBinding } from 'vue'

const vLazy = (observer: IntersectionObserver) => {
  return {
    beforeMount: (el: HTMLImageElement, binding: DirectiveBinding) => {
      el.classList.add('op-lazyload')
      el.dataset.lazyKey = binding.value
      observer.observe(el)
    },
  }
}

const lazyPlugin = {
  install(app: App) {
    //一种方法,以异步地观察目标元素与祖先元素或与顶级视口相交时的更改。
    const observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((item) => {
          if (item.isIntersecting) {
            // 开始加载图片,把 data-origin 的值放到 src
            const el = item.target as HTMLImageElement
            el.src = el.dataset.lazyKey as string
            el.classList.remove('op-lazyload')
            // 停止监听
            observer.unobserve(el)
          }
        })
      },
      {
        // 交叉视图的 100ps,才开始派发事件
        rootMargin: '0px 0px -100px 0px',
      }
    )
    //添加一个名字叫lazy的指令 // <img v-lazy="" />
    app.directive('lazy', vLazy(observer))
  },
}

export default lazyPlugin
//第二个参数是 触发这个指令时要做的逻辑,可以在一些生命周期函数中执行内容,
//本文是在beforeMount函数添加逻辑
// export declare interface ObjectDirective<T = any, V = any> {
//   created?: DirectiveHook<T, null, V>;
//   beforeMount?: DirectiveHook<T, null, V>;
//   mounted?: DirectiveHook<T, null, V>;
//   beforeUpdate?: DirectiveHook<T, VNode<any, T>, V>;
//   updated?: DirectiveHook<T, VNode<any, T>, V>;
//   beforeUnmount?: DirectiveHook<T, null, V>;
//   unmounted?: DirectiveHook<T, null, V>;
//   getSSRProps?: SSRDirectiveHook;
//   deep?: boolean;
// }

使用也很简单,第一步先添加插件:

app.use(lazyPlugin)

 然后在图片标签处代替rsc

<img class="item__poster" v-lazy="data.postUrl" />