前言
最近用Vue3开发遇到一个场景,点击按钮以外区域时,触发对应事件。
在Vue2中比较普遍的方法是封装自定义指令来实现,不过既然用Vue3了,就尝试一下它的新特性,用hooks的方式来实现。
方案一 自定义指令
<div
class="show_remark"
:class="[{ remarkType: remarkType }]"
v-click-outside="onClickOutside"
>
{{ remarkType ? "确认重置" : "重置" }}
</div>
// 定义按钮以外事件
const vClickOutside = {
mounted(
el,
binding
) {
function eventHandler(e) {
// 如果点击的是按钮
if (el.contains(e.target)) {
remarkType.value = !remarkType.value;
if (!remarkType.value) {
inputText.value = "";
clearAll();
}
return false;
}
// 点击的是按钮以外的区域
// 如果绑定的参数是函数,正常情况也应该是函数执行
if (binding.value && typeof binding.value === "function") {
binding.value(e);
}
}
// 用于销毁前注销事件监听
el.__click_outside__ = eventHandler;
// 添加事件监听
document.addEventListener("click", eventHandler);
},
beforeUnmount(el) {
// 移除事件监听
document.removeEventListener("click", el.__click_outside__);
// 删除无用属性
delete el.__click_outside__;
},
};
// 自定义指令参数,点击外部区域的处理函数,如关闭弹窗
const onClickOutside = () => {
remarkType.value = false;
};
方案二 自定义hooks
import { ref, onMounted, onUnmounted,Ref } from 'vue'
// 把绑定的元素传进来
const useClickOutside = (elementRef:Ref<null | HTMLElement>) => {
const isClickOutside = ref(false)
const handler = (e: MouseEvent) => {
if (elementRef.value) {
// 判断点击的地方是否在元素以外
if (elementRef.value.contains(e.target as HTMLElement)) {
isClickOutside.value = false
} else {
isClickOutside.value = true
}
}
}
onMounted(() => {
document.addEventListener("click", handler);
});
onUnmounted(() => {
document.removeEventListener("click", handler);
});
return isClickOutside
}
export default useClickOutside
使用方法
const isClickOutside = useClickOutside(dropDownRef);
//通过watch来监听isClickOutside的变化
watch(isClickOutside, (newValue) => {
// 。。。。。。
});
END
- 希望这篇文章可以帮助到有需要的小伙伴们,有问题可以评论或私信我呀🤞🤞