利用vueuse/core插件
pnpm i @vueuse/core
需要引入 useIntersectionObserver // 响应式监听目标元素的可见性。
具体详见 useIntersectionObserver | VueUse中文文档
1、创建指令
'use strict'
import { useIntersectionObserver } from '@vueuse/core'
const avatarLoad = (el: any, binding: any, vnode?: any) => {
let imgURL = binding.value // 获取图片地址
// 可以根据不同业务自行处理逻辑
// 加入延时,效果更加明显
setTimeout(() => {
el.innerHTML = `<img src="${imgURL}" width="100%" height="100%" style="border-radius:50%;position:relative">`
}, 3000)
}
export default {
async mounted(el: any, binding: any, vnode?: any) {
const { stop } = useIntersectionObserver(
el,
// isIntersecting 布尔值,元素可见为 true,元素不可见为 false
([{ isIntersecting }], observerElement) => {
// 图片标签是否可见
if (isIntersecting) {
// 如果目标可见,替换图片地址,自动加载图片
// el.src = binding.value
avatarLoad(el, binding, vnode)
// 如果图片地址是错误的,无法加载图片,显示占位图(默认图)
// el.onerror = () => {
// el.src = ''
// }
stop()
}
},
// 🔔优化: 0 元素刚进入可视区触发,1 表示元素完整进入可视区才触发
{ threshold: [0] }
)
},
updated(el: any, binding: any, vnode?: any) {
const arg = binding.arg || '' // 传入指令参数名称
const oldArg = el.oldArg || '' // 保存前一次指令执行时的参数名称
console.log('updated', el, binding, vnode, arg, oldArg)
}
}
2、这里我获取所有指令进行注册
2.1 创建directives目录,index.ts文件,获取目录下的执行,通过传入的vue实例进行注册
const files = import.meta.globEager('./*.ts')
const modules: any = {}
for (const key in files) {
if (Object.prototype.hasOwnProperty.call(files, key)) {
modules[key.replace(/(\.\/|\.ts)/g, '')] = files[key].default
}
}
// console.log('modules', modules)
export const directivesHook = (app: any) => {
for (const key in modules) {
if (Object.prototype.hasOwnProperty.call(modules, key)) {
app.directive(key, modules[key])
}
}
}
2.2 在main.ts中传入vue实例
const app = createApp(App)
// 指令
directivesHook(app)
3、在组件中使用指令
<div class="avatar-lazy" v-avarat:today="'https://gimg3.baidu.com/topone/src=https%3A%2F%2Fbkimg.cdn.bcebos.com%2Fpic%2F5fdf8db1cb134954b37001e85c4e9258d0094ad4%3Fx-bce-process%3Dimage%2Fresize%2Cm_pad%2Cw_348%2Ch_348%2Ccolor_ffffff&refer=http%3A%2F%2Fwww.baidu.com&app=2011&size=f200,200&n=0&g=0n&er=404&q=75&fmt=auto&maxorilen2heic=2000000?sec=1692118800&t=d9eba140d99346ddfd25fe5d00b16944'"></div>
可在v-xxx指令后传入指定参数名称,通常用作更新时进行比较,来判断是否执行特定的业务逻辑