From 61d6312783f05c2226a0ea7f5a58bd8375ad3cb7 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Tue, 2 May 2023 23:36:12 +0800 Subject: [PATCH] fix: dropdown menu hide error --- components/menu/src/Menu.tsx | 60 ++++++++++----------- components/menu/src/PopupTrigger.tsx | 5 +- components/menu/src/SubMenu.tsx | 2 +- components/menu/src/hooks/useMenuContext.ts | 5 -- components/vc-dropdown/Dropdown.tsx | 1 - components/vc-trigger/Popup/index.tsx | 3 +- components/vc-trigger/Trigger.tsx | 23 +++++--- 7 files changed, 50 insertions(+), 49 deletions(-) diff --git a/components/menu/src/Menu.tsx b/components/menu/src/Menu.tsx index 75c65723b..9730b5a1a 100644 --- a/components/menu/src/Menu.tsx +++ b/components/menu/src/Menu.tsx @@ -65,7 +65,7 @@ export const menuProps = () => ({ mode: { type: String as PropType, default: 'vertical' }, inlineIndent: { type: Number, default: 24 }, - subMenuOpenDelay: { type: Number, default: 0.1 }, + subMenuOpenDelay: { type: Number, default: 0 }, subMenuCloseDelay: { type: Number, default: 0.1 }, builtinPlacements: { type: Object as PropType }, @@ -201,41 +201,40 @@ export default defineComponent({ // >>>>> Trigger select const triggerSelection = (info: MenuInfo) => { - if (!props.selectable) { - return; - } - // Insert or Remove - const { key: targetKey } = info; - const exist = mergedSelectedKeys.value.includes(targetKey); - let newSelectedKeys: Key[]; + if (props.selectable) { + // Insert or Remove + const { key: targetKey } = info; + const exist = mergedSelectedKeys.value.includes(targetKey); + let newSelectedKeys: Key[]; - if (props.multiple) { - if (exist) { - newSelectedKeys = mergedSelectedKeys.value.filter(key => key !== targetKey); + if (props.multiple) { + if (exist) { + newSelectedKeys = mergedSelectedKeys.value.filter(key => key !== targetKey); + } else { + newSelectedKeys = [...mergedSelectedKeys.value, targetKey]; + } } else { - newSelectedKeys = [...mergedSelectedKeys.value, targetKey]; + newSelectedKeys = [targetKey]; } - } else { - newSelectedKeys = [targetKey]; - } - // Trigger event - const selectInfo: SelectInfo = { - ...info, - selectedKeys: newSelectedKeys, - }; - if (!shallowEqual(newSelectedKeys, mergedSelectedKeys.value)) { - if (props.selectedKeys === undefined) { - mergedSelectedKeys.value = newSelectedKeys; - } - emit('update:selectedKeys', newSelectedKeys); - if (exist && props.multiple) { - emit('deselect', selectInfo); - } else { - emit('select', selectInfo); + // Trigger event + const selectInfo: SelectInfo = { + ...info, + selectedKeys: newSelectedKeys, + }; + if (!shallowEqual(newSelectedKeys, mergedSelectedKeys.value)) { + if (props.selectedKeys === undefined) { + mergedSelectedKeys.value = newSelectedKeys; + } + emit('update:selectedKeys', newSelectedKeys); + if (exist && props.multiple) { + emit('deselect', selectInfo); + } else { + emit('select', selectInfo); + } } } - + // Whatever selectable, always close it if (mergedMode.value !== 'inline' && !props.multiple && mergedOpenKeys.value.length) { triggerOpenKeys(EMPTY_LIST); } @@ -432,7 +431,6 @@ export default defineComponent({ registerMenuInfo, unRegisterMenuInfo, selectedSubMenuKeys, - isRootMenu: shallowRef(true), expandIcon, forceSubMenuRender: computed(() => props.forceSubMenuRender), rootClassName: hashId, diff --git a/components/menu/src/PopupTrigger.tsx b/components/menu/src/PopupTrigger.tsx index a061d9200..93c9183fa 100644 --- a/components/menu/src/PopupTrigger.tsx +++ b/components/menu/src/PopupTrigger.tsx @@ -39,7 +39,6 @@ export default defineComponent({ subMenuCloseDelay, builtinPlacements, triggerSubMenuAction, - isRootMenu, forceSubMenuRender, motion, defaultMotions, @@ -91,9 +90,7 @@ export default defineComponent({ rootClassName.value, )} stretch={mode === 'horizontal' ? 'minWidth' : null} - getPopupContainer={ - isRootMenu.value ? getPopupContainer.value : triggerNode => triggerNode.parentNode - } + getPopupContainer={getPopupContainer.value} builtinPlacements={placement.value} popupPlacement={popupPlacement.value} popupVisible={innerVisible.value} diff --git a/components/menu/src/SubMenu.tsx b/components/menu/src/SubMenu.tsx index 54c94fc1a..5d5fdbd78 100644 --- a/components/menu/src/SubMenu.tsx +++ b/components/menu/src/SubMenu.tsx @@ -302,7 +302,7 @@ export default defineComponent({ onVisibleChange={onPopupVisibleChange} v-slots={{ popup: () => ( - + ; } export interface MenuContextProps { - isRootMenu: Ref; rootClassName: Ref; registerMenuInfo: (key: string, info: StoreMenuInfo) => void; unRegisterMenuInfo: (key: string) => void; @@ -114,7 +113,6 @@ const MenuContextProvider = defineComponent({ props: { mode: { type: String as PropType, default: undefined }, overflowDisabled: { type: Boolean, default: undefined }, - isRootMenu: { type: Boolean, default: undefined }, }, setup(props, { slots }) { const menuContext = useInjectMenu(); @@ -124,9 +122,6 @@ const MenuContextProvider = defineComponent({ if (props.mode !== undefined) { newContext.mode = toRef(props, 'mode'); } - if (props.isRootMenu !== undefined) { - newContext.isRootMenu = toRef(props, 'isRootMenu'); - } if (props.overflowDisabled !== undefined) { newContext.overflowDisabled = toRef(props, 'overflowDisabled'); } diff --git a/components/vc-dropdown/Dropdown.tsx b/components/vc-dropdown/Dropdown.tsx index fcd623364..7ce3c67f6 100644 --- a/components/vc-dropdown/Dropdown.tsx +++ b/components/vc-dropdown/Dropdown.tsx @@ -70,7 +70,6 @@ export default defineComponent({ const extraOverlayProps = { prefixCls: `${props.prefixCls}-menu`, onClick, - getPopupContainer: () => triggerRef.value.getPopupDomNode(), }; return ( diff --git a/components/vc-trigger/Popup/index.tsx b/components/vc-trigger/Popup/index.tsx index 58002248c..9fffe1235 100644 --- a/components/vc-trigger/Popup/index.tsx +++ b/components/vc-trigger/Popup/index.tsx @@ -13,6 +13,7 @@ export default defineComponent({ const innerVisible = shallowRef(false); const inMobile = shallowRef(false); const popupRef = shallowRef(); + const rootRef = shallowRef(); watch( [() => props.visible, () => props.mobile], () => { @@ -45,7 +46,7 @@ export default defineComponent({ ); return ( -
+
{popupNode}
diff --git a/components/vc-trigger/Trigger.tsx b/components/vc-trigger/Trigger.tsx index e11af9a0e..418a20b5d 100644 --- a/components/vc-trigger/Trigger.tsx +++ b/components/vc-trigger/Trigger.tsx @@ -11,7 +11,6 @@ import { getSlot, findDOMNode, } from '../_util/props-util'; -import { requestAnimationTimeout, cancelAnimationTimeout } from '../_util/requestAnimationTimeout'; import addEventListener from '../vc-util/Dom/addEventListener'; import Popup from './Popup'; import { getAlignFromPlacement, getAlignPopupClassName } from './utils/alignUtil'; @@ -43,7 +42,6 @@ const ALL_HANDLERS = [ 'onBlur', 'onContextmenu', ]; - export default defineComponent({ compatConfig: { MODE: 3 }, name: 'Trigger', @@ -107,7 +105,11 @@ export default defineComponent({ setPortal, vcTriggerContext: inject( 'vcTriggerContext', - {} as { onPopupMouseDown?: (...args: any[]) => void }, + {} as { + onPopupMouseDown?: (...args: any[]) => void; + onPopupMouseenter?: (...args: any[]) => void; + onPopupMouseleave?: (...args: any[]) => void; + }, ), popupRef, setPopupRef, @@ -165,6 +167,8 @@ export default defineComponent({ created() { provide('vcTriggerContext', { onPopupMouseDown: this.onPopupMouseDown, + onPopupMouseenter: this.onPopupMouseenter, + onPopupMouseleave: this.onPopupMouseleave, }); useProvidePortal(this); }, @@ -256,6 +260,10 @@ export default defineComponent({ }, onPopupMouseenter() { + const { vcTriggerContext = {} } = this; + if (vcTriggerContext.onPopupMouseenter) { + vcTriggerContext.onPopupMouseenter(); + } this.clearDelayTimer(); }, @@ -269,6 +277,10 @@ export default defineComponent({ return; } this.delaySetPopupVisible(false, this.$props.mouseLeaveDelay); + const { vcTriggerContext = {} } = this; + if (vcTriggerContext.onPopupMouseleave) { + vcTriggerContext.onPopupMouseleave(e); + } }, onFocus(e) { @@ -359,7 +371,6 @@ export default defineComponent({ this.mouseDownTimeout = setTimeout(() => { this.hasPopupMouseDown = false; }, 0); - if (vcTriggerContext.onPopupMouseDown) { vcTriggerContext.onPopupMouseDown(...args); } @@ -574,7 +585,7 @@ export default defineComponent({ this.clearDelayTimer(); if (delay) { const point = event ? { pageX: event.pageX, pageY: event.pageY } : null; - this.delayTimer = requestAnimationTimeout(() => { + this.delayTimer = setTimeout(() => { this.setPopupVisible(visible, point); this.clearDelayTimer(); }, delay); @@ -585,7 +596,7 @@ export default defineComponent({ clearDelayTimer() { if (this.delayTimer) { - cancelAnimationTimeout(this.delayTimer); + clearTimeout(this.delayTimer); this.delayTimer = null; } },