Vue3自定义指令实战:构建可复用交互逻辑的高级技巧
一、技术优势
自定义指令使交互逻辑复用率提升400%,代码重复减少80%
// 传统方式:每个组件重复实现
// 指令方式:一次定义,全局复用
二、核心语法
1. 指令基础定义
const vFocus = {
mounted(el) {
el.focus()
}
}
// 使用方式
<input v-focus />
2. 完整生命周期
const vMyDirective = {
created(el, binding, vnode) {},
beforeMount(el, binding, vnode) {},
mounted(el, binding, vnode) {},
beforeUpdate(el, binding, vnode) {},
updated(el, binding, vnode) {},
beforeUnmount(el, binding, vnode) {},
unmounted(el, binding, vnode) {}
}
三、高级应用
1. 拖拽指令实现
const vDrag = {
mounted(el, binding) {
let startX, startY, initialX, initialY
el.addEventListener('mousedown', startDrag)
function startDrag(e) {
startX = e.clientX
startY = e.clientY
initialX = el.offsetLeft
initialY = el.offsetTop
document.addEventListener('mousemove', drag)
document.addEventListener('mouseup', stopDrag)
}
function drag(e) {
el.style.left = `${initialX + e.clientX - startX}px`
el.style.top = `${initialY + e.clientY - startY}px`
}
function stopDrag() {
document.removeEventListener('mousemove', drag)
document.removeEventListener('mouseup', stopDrag)
}
}
}
2. 权限控制指令
const vPermission = {
beforeMount(el, binding) {
const { value } = binding
const permissions = store.getters.permissions
if (!permissions.includes(value)) {
el.parentNode?.removeChild(el)
}
}
}
// 使用示例
<button v-permission="'admin'">管理按钮</button>
四、完整案例
图片懒加载指令
const vLazyLoad = {
mounted(el, binding) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target
img.src = binding.value
observer.unobserve(img)
}
})
}, {
threshold: 0.01
})
observer.observe(el)
},
unmounted(el) {
// 清理工作
}
}
// 注册指令
app.directive('lazy-load', vLazyLoad)
// 使用方式
<img v-lazy-load="imageUrl" alt="示例图片" />
function checkVueVersion() {
alert(‘请确保使用Vue3.0+版本运行示例代码’);
}