update clickoutside 方法优化

This commit is contained in:
2026-03-17 14:51:32 +08:00
parent 384f43c45c
commit e00f2f1bb7

View File

@@ -2,6 +2,14 @@ import { ref, onMounted, onBeforeUnmount } from 'vue';
export function useClickOutside(popoverRef: any) {
const popoverVisible = ref(false);
let hideTimer: number | null = null;
const clearHideTimer = () => {
if (hideTimer !== null) {
clearTimeout(hideTimer);
hideTimer = null;
}
};
const handleClickOutside = (event: Event) => {
const popover = popoverRef.value;
@@ -26,13 +34,13 @@ export function useClickOutside(popoverRef: any) {
if (isInPopper) {
return;
}
// 点击外部时关闭 popover
// 点击外部时关闭popover
clearHideTimer();
popoverVisible.value = false;
};
const handleMouseMove = (event: MouseEvent) => {
const popover = popoverRef.value;
if (!popover) return;
if (!popover || !popoverVisible.value) return;
const triggerEl = popover.popperRef?.triggerRef;
const popperEl = popover.popperRef?.popperRef;
@@ -50,45 +58,27 @@ export function useClickOutside(popoverRef: any) {
// 如果鼠标在当前popover内或者在其他popper类组件内则显示popover
if (isInCurrentPopover || isInOtherPopper) {
clearHideTimer();
popoverVisible.value = true;
} else {
// 否则隐藏popover
popoverVisible.value = false;
// 否则设置100ms后隐藏popover
clearHideTimer();
hideTimer = window.setTimeout(() => {
popoverVisible.value = false;
hideTimer = null;
}, 100);
}
};
const handleScroll = (event: Event) => {
const popover = popoverRef.value;
if (!popover) return;
const triggerEl = popover.popperRef?.triggerRef;
const popperEl = popover.popperRef?.popperRef;
const target = event.target as HTMLElement;
// 检查滚动是否发生在当前popover或触发元素内
const isInCurrentPopover = triggerEl?.contains(target) || popperEl?.contains(target);
// 检查滚动是否发生在其他popper类组件内包括时间选择器等
const isInAnyPopper =
target.closest('.el-popper') ||
target.closest('.el-picker-panel') ||
target.closest('.el-select-dropdown') ||
target.closest('.el-cascader-panel');
// 只有当滚动不在任何popover类组件内时才关闭popover
if (!isInCurrentPopover && !isInAnyPopper) {
popoverVisible.value = false;
}
};
onMounted(() => {
document.addEventListener('click', handleClickOutside);
document.addEventListener('scroll', handleScroll, true); // 使用捕获阶段监听滚动事件
// document.addEventListener('mousemove', handleMouseMove);
document.addEventListener('mousemove', handleMouseMove);
});
onBeforeUnmount(() => {
clearHideTimer();
document.removeEventListener('click', handleClickOutside);
document.removeEventListener('scroll', handleScroll, true); // 使用捕获阶段移除滚动事件
// document.removeEventListener('mousemove', handleMouseMove);
document.removeEventListener('mousemove', handleMouseMove);
});
return {