我们经常在开发过程中,会遇到这些问题:
- 怎么实现点击空白处关闭指定盒子?
- 怎么实现点击空白处收起下拉框?
即,怎么触发点击空白处事件,怎么触发 点击非自身dom而触发的事件?
在vue3当中,使用自定义指令解决这个问题:
在utils/directives.ts
中
// 自定义指令点击非自身事件(空白处)
const clickOutSide = {
beforeMount(el: any, binding: any) {
function documentHandler(e: any) {
console.log(e)
// 这里判断点击的元素是否是本身,是本身,则返回
if (el.contains(e.target)) return false;
// 判断指令中是否绑定了函数
console.log('判断指令中是否绑定了函数', binding)
if (binding.value) {
console.log('有绑定函数,则执行函数')
// 有绑定函数,则执行函数
binding.value(e);
}
}
// 给当前元素绑定个私有变量,方便在unmounted中可以解除事件监听
el.__vueClickOutside__ = documentHandler;
document.addEventListener('click', documentHandler);
},
unmounted(el: any) {
document.removeEventListener('click', el.__vueClickOutside__);
delete el.__vueClickOutside__;
}
}
const directives = {
install: function (app: any) {
app.directive('clickOutSide', clickOutSide)
}
};
export default directives;
调用
在main.ts
中
import Directives from '@/utils/directives';
const app = createApp(App)
app.use(router)
.use(Directives)
在页面组件中
<template>
...
<p v-clickOutSide="clickNoDom">
这个点击不触发
</p>
...
</template>
这样在点击非p
标签时,就会触发clickNoDom()
方法。
Tip:
另外有一篇关于vue3自定义指令的文章:👇