在滑动列表视图中如果有网络图片需要加载直接给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" />
标签:el,Vue,const,observer,DirectiveHook,item,加载,图片 From: https://www.cnblogs.com/duzhaoquan/p/17824694.html