在vue中,组件是主要的构建模块,组合式函数侧重于有状态的逻辑,自定义指令则主要是为了重用涉及普通元素的底层 DOM 访问的逻辑。在官方文档中,它最简单的用法如下:
<script setup>
// 在模板中启用 v-focus
const vFocus = {
mounted: (el) => el.focus()
}
</script>
<template>
<input v-focus />
</template>
有点类似在对象中加一个钩子函数和一个回调。 再进一步,需要将自定义指令设计成一个全局指令,此时需要在createApp()返回的全局变量中使用direactive方法创建自定义指令,
const app = createApp(App)
app.directive('lazy-img', (el, bind) => {
console.log(el, bind);
const { stop } = useIntersectionObserver(
el,
([{ isIntersecting }]) => {
if (isIntersecting) {
el.src = 文件地址
}
console.log(isIntersecting);
},
)
}
)
app.mount('#app')
再进一步,为了节省main.js的代码量,可以尝试在外部js文件中封装好自定义组件逻辑,在main.js中直接挂载就好了,具体操作如下:
// 定义懒加载插件
import { useIntersectionObserver } from '@vueuse/core'
export const lazyPlugin = {
install (app) {
// 懒加载指令逻辑
app.directive('img-lazy', {
mounted (el, binding) {
// el: 指令绑定的那个元素 img
// binding: binding.value 指令等于号后面绑定的表达式的值 图片url
console.log(el, binding.value)
const { stop } = useIntersectionObserver(
el,
([{ isIntersecting }]) => {
console.log(isIntersecting)
if (isIntersecting) {
// 进入视口区域
el.src = binding.value
stop()
}
},
)
}
})
}
}
//main.js
// 全局指令注册
import { directivePlugin } from '@/directives'
app.use(directivePlugin)