Modal组件复用useClickOutside遇到的问题
来源:10-5 Modal组件编码
津白
2020-11-27
这里也可以复用useClickOutside,点击modal以外的区域关闭modal。但是面临一个问题,就是删除按钮也是在modal区域外的,所以会判断为isClickOutside为真,导致modal不能正常点开。我的解决方法是在useClickOutside里增加一个可选参数,接收clickOutside判断时排除在外的HTMLELEMENT(也就是在modal之外但是被算为是modal的一份子的dom,比如这里的删除按钮),主要代码如下图。但是这就需要调用Modal的组件多穿一个参数,不知道有没有更优雅的解决方法。
// Modal.vue
const modalRef = ref<null | HTMLElement>(null)
const buttonRef = computed(() => props.buttonRef)
const isClickOutside = useClickOutside(modalRef, buttonRef)
watch([() => props.visible, isClickOutside], (n, o) => {
const prevVisible = o[0]
if (prevVisible && isClickOutside.value) {
context.emit('modal-on-close')
}
})
// useClickOutside.ts
export default function useClickOutside (elementRef: Ref<null | HTMLElement>, exclusionRef?: Ref<HTMLElement>) {
const isClickOutside = ref(false)
const handler = (e: MouseEvent) => {
// clicked outside the element
if (elementRef.value && !elementRef.value.contains(e.target as HTMLElement)) {
// if clicked in the exclusion element, do not count as clicked inside
if (exclusionRef && exclusionRef.value && exclusionRef.value.contains(e.target as HTMLElement)) {
isClickOutside.value = false
} else {
isClickOutside.value = true
}
} else {
isClickOutside.value = false
}
}
onMounted(() => {
document.addEventListener('click', handler)
})
onUnmounted(() => {
document.removeEventListener('click', handler)
})
return isClickOutside
}
写回答
1回答
-
同学你好 我觉得你做的很好 没啥问题 假如说我能想到的优化点就是,第二个参数有可能是 DOM 元素的数组,我们可能希望 把一些节点(不仅仅是一个排除出去)
第二个优化 我想 useClickOutside 不仅返回 true 或者 false,还可以返回当前节点,这时候你就可以在 useClickOutside 这个文件进行判断了,这样做的好处就是 这个 hook 功能就很专注并且简单,它只有一个目的,就是判断是否在外面,而至于到了外面还要触发什么操作,我把节点提供给你,你自己根据节点进行判断。
112020-11-30
相似问题