目前在使用Vue3+TypeScript开发前端项目。时长遇到"手抖"选手,导致多次请求等问题。
Vue 3 允许你创建自定义指令,以便在 DOM 上应用一些特殊的行为。自定义指令具有几个可用的钩子函数,如 bind、inserted、update、componentUpdated 和 unbind,它们会在指令的不同生命周期阶段被调用。
下面是如何在 Vue 3 中创建一个自定义指令的基本步骤:
定义自定义指令
你可以在组件内部定义指令,也可以全局定义它们。
局部定义(在组件内部):
javascript
export default {
directives: {
focus: {
// 当被绑定的元素插入到 DOM 中时调用
inserted: function (el) {
el.focus()
}
}
}
}
全局定义:
javascript
const app = Vue.createApp({})
app.directive('focus', {
inserted: function (el) {
el.focus()
}
})
使用自定义指令
在你的模板中,你可以像使用内置指令一样使用自定义指令:
html
<template>
<input v-focus>
</template>
使用钩子函数
除了 inserted,你还可以使用其他钩子函数,如 bind、update、componentUpdated 和 unbind。
例如,下面的指令会在元素的值更新时改变其颜色:
javascript
app.directive('color-on-update', {
bind(el, binding, vnode) {
el.style.color = 'black'
},
update(el, binding, vnode, prevVnode) {
el.style.color = 'red'
}
})
然后,你可以在模板中这样使用它:
html
<template>
<p v-color-on-update="someReactiveProperty">This text will turn red when `someReactiveProperty` changes.</p>
</template>
传递参数给自定义指令
你可以通过指令的值、修饰符或表达式传递参数给自定义指令。例如:
html
<template>
<p v-highlight="'yellow'">Highlighted text</p>
</template>
在自定义指令中,你可以通过 binding.value 访问这个值:
javascript
app.directive('highlight', {
bind(el, binding) {
el.style.backgroundColor = binding.value
}
})
动态指令参数
Vue 3 还支持动态指令参数,这意味着你可以根据组件的状态动态地改变指令的行为。例如:
html
<template>
<p v-highlight:[dynamicColor]>Dynamically highlighted text</p>
</template>
<script>
export default {
data() {
return {
dynamicColor: 'blue'
}
}
}
</script>
在自定义指令中,你可以这样处理动态参数:
javascript
app.directive('highlight', {
bind(el, binding) {
const color = binding.arg || 'defaultColor' // 如果动态参数不存在,则使用默认值
el.style.backgroundColor = color
}
})
通过这些方法,我们来创建一个防抖指令
typescript
// 定义防止重复点击的指令
export const preventReClick = {
created(el:any, binding:any, vnode:any, prevVnode:any) {
console.log(vnode,prevVnode);
el.addEventListener('click', (e:any)=>customClick(e,binding,el));
},
// 离开一定要销毁卸载
unmounted(el:any, binding:any, vnode:any) {
console.log(binding,vnode);
el.removeEventListener('click', customClick);
},
};
// 逻辑封装
const customClick = (e:any,binding:any,el:any) => {
//阻止事件冒泡
e.stopPropagation()
if (!el.disabled) { // 判断条件
el.disabled = true
setTimeout(() => {
el.disabled = false
},binding.arg||1000)
// 正常触发点击事件
binding.value();
} else {
// 已经成功拦截点击事件
console.log('已经成功拦截点击事件');
};
};
//指令抛出
export const setupAuthDirective = (app:any) => {
app.directive('click', preventReClick);
};