1. 自定义指令
在main.js中定义自定义指令
// 省略其他
const app = createApp(App)
app.directive('imgLazy', {
mounted (el, binding) {
console.log(el,binding,'imgLazy')
}
})
2. 使用自定义指令
<img v-imgLazy="src" ></img>
3. 输出自定义指令钩子函数的两个参数
可以看到:
el是指令绑定到的dom元素binding.value是:
<dom v-imgLazy=" binding.value的值"/>
4. 将代码封装到directives/index.js
const myDirective = {
install (app) {
// 自定义指令
app.directive('imgLazy', {
mounted (el, binding) {
console.log(el,binding,'imgLazy')
}
})
}
}
export default myDirective
在main.js中引入,并使用
// 省略其他
// 引入全局指令
import myDirective from '@/directives'
const app = createApp(App)
app.use(store).use(router).use(myPlugin).use(myDirective).mount('#app')
5. 完善封装的函数
这里依旧用到数据懒加载插件 @vueuse/core
插件的简单用法,请看vue3复用数据懒加载
借用数据懒加载,在当前视图显示时再去请求图片,当请求还未回来之前显示默认图片
import { useIntersectionObserver } from '@vueuse/core'
// 默认图片
import defaultImage from '@/assets/images/200.png'
const myDirective = {
install (app) {
// 自定义指令
app.directive('imgLazy', {
mounted (el, binding) {
el.src = defaultImage
// el是指令绑定到的dom元素
// binding.value是:<dom v-imgLazy=" binding.value的值"/>
console.log(el, binding, 'imgLazy')
const { stop } = useIntersectionObserver(el,
([{ isIntersecting }], abserveDom) => {
if (isIntersecting) {
stop()
// 给dom元素设置src属性值
el.src = binding.value
el.onerror = () => {
el.src = defaultImage
}
}
},
{ threshold: 0 }
)
}
})
}
}
export default myDirective
6. 实现的效果图
网络较慢的时候:
网络正常时: