From 1ae0d519d3fbb9afc34d1d48270b722d7ca0e6a4 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Sun, 12 Sep 2021 13:48:01 +0800 Subject: [PATCH] fix: menu arrow not work --- components/menu/src/Menu.tsx | 26 +++--- components/menu/src/SubMenu.tsx | 90 +++++++++++---------- components/menu/src/hooks/useMenuContext.ts | 2 +- components/vc-overflow/Item.tsx | 29 ++++--- components/vc-overflow/Overflow.tsx | 35 ++++---- components/vc-overflow/RawItem.tsx | 5 +- 6 files changed, 99 insertions(+), 88 deletions(-) diff --git a/components/menu/src/Menu.tsx b/components/menu/src/Menu.tsx index 5631bb8ad..4c7d1a1a9 100644 --- a/components/menu/src/Menu.tsx +++ b/components/menu/src/Menu.tsx @@ -346,17 +346,21 @@ export default defineComponent({ }; const lastVisibleIndex = ref(0); - const expandIcon: MenuProps['expandIcon'] = opt => { - let icon = props.expandIcon || slots.expandIcon; - icon = typeof icon === 'function' ? icon(opt) : icon; - return cloneElement( - icon, - { - class: `${prefixCls.value}-submenu-expand-icon`, - }, - false, - ); - }; + const expandIcon = computed(() => + props.expandIcon || slots.expandIcon + ? opt => { + let icon = props.expandIcon || slots.expandIcon; + icon = typeof icon === 'function' ? icon(opt) : icon; + return cloneElement( + icon, + { + class: `${prefixCls.value}-submenu-expand-icon`, + }, + false, + ); + } + : null, + ); useProvideMenu({ store, prefixCls, diff --git a/components/menu/src/SubMenu.tsx b/components/menu/src/SubMenu.tsx index 57fea3003..869d1f1b1 100644 --- a/components/menu/src/SubMenu.tsx +++ b/components/menu/src/SubMenu.tsx @@ -230,41 +230,42 @@ export default defineComponent({ ); return () => { - const icon = getPropsSlot(slots, props, 'icon'); - const title = renderTitle(getPropsSlot(slots, props, 'title'), icon); const subMenuPrefixClsValue = subMenuPrefixCls.value; - const expandIcon = props.expandIcon || slots.expandIcon || menuExpandIcon; - let titleNode = ( -
- {title} - - {/* Only non-horizontal mode shows the icon */} - {mode.value !== 'horizontal' && expandIcon ? ( - expandIcon({ ...props, isOpen: open.value }) - ) : ( - - )} -
- ); + let baseTitleNode = () => { + const icon = getPropsSlot(slots, props, 'icon'); + const expandIcon = props.expandIcon || slots.expandIcon || menuExpandIcon.value; + const title = renderTitle(getPropsSlot(slots, props, 'title'), icon); + return ( +
+ {title} + {/* Only non-horizontal mode shows the icon */} + {mode.value !== 'horizontal' && expandIcon ? ( + expandIcon({ ...props, isOpen: open.value }) + ) : ( + + )} +
+ ); + }; + let titleNode = () => null; if (!overflowDisabled.value && mode.value !== 'inline') { - const triggerMode = triggerModeRef.value; - titleNode = ( + titleNode = () => ( - {titleNode} + {baseTitleNode()} ); } else { // 包裹一层,保持结构一致,防止动画丢失 // https://github.com/vueComponent/ant-design-vue/issues/4325 - titleNode = {titleNode}; + titleNode = () => {baseTitleNode()}; } return ( @@ -311,16 +312,21 @@ export default defineComponent({ onMouseenter={onMouseEnter} onMouseleave={onMouseLeave} data-submenu-id={key} - > - {titleNode} + v-slots={() => { + return ( + <> + {titleNode()} - {/* Inline mode */} - {!overflowDisabled.value && ( - - {slots.default?.()} - - )} - + {/* Inline mode */} + {!overflowDisabled.value && ( + + {slots.default?.()} + + )} + + ); + }} + > ); }; diff --git a/components/menu/src/hooks/useMenuContext.ts b/components/menu/src/hooks/useMenuContext.ts index 62d6a5828..86d8a17e6 100644 --- a/components/menu/src/hooks/useMenuContext.ts +++ b/components/menu/src/hooks/useMenuContext.ts @@ -75,7 +75,7 @@ export interface MenuContextProps { // // Icon // itemIcon?: RenderIconType; - expandIcon?: (p?: { isOpen: boolean; [key: string]: any }) => any; + expandIcon?: ComputedRef<(p?: { isOpen: boolean; [key: string]: any }) => any>; // // Function onItemClick: MenuClickEventHandler; diff --git a/components/vc-overflow/Item.tsx b/components/vc-overflow/Item.tsx index b374a9c8e..2cd358491 100644 --- a/components/vc-overflow/Item.tsx +++ b/components/vc-overflow/Item.tsx @@ -71,18 +71,6 @@ export default defineComponent({ overflowProps['aria-hidden'] = true; } - const itemNode = ( - - {childNode} - - ); - // 使用 disabled 避免结构不一致 导致子组件 rerender return ( { internalRegisterSize(offsetWidth); }} - > - {itemNode} - + v-slots={{ + default: () => ( + + {childNode} + + ), + }} + > ); }; }, diff --git a/components/vc-overflow/Overflow.tsx b/components/vc-overflow/Overflow.tsx index 82d714984..dd615aa3c 100644 --- a/components/vc-overflow/Overflow.tsx +++ b/components/vc-overflow/Overflow.tsx @@ -302,7 +302,7 @@ const Overflow = defineComponent({ }; // >>>>> Rest node - let restNode: VueNode; + let restNode = () => null; const restContextProps = { order: displayRest ? mergedDisplayCount.value : Number.MAX_SAFE_INTEGER, className: `${itemPrefixCls.value}-rest`, @@ -313,19 +313,21 @@ const Overflow = defineComponent({ if (!renderRawRest) { const mergedRenderRest = renderRest || defaultRenderRest; - restNode = ( + restNode = () => ( - {typeof mergedRenderRest === 'function' - ? mergedRenderRest(omittedItems.value) - : mergedRenderRest} - + v-slots={{ + default: () => + typeof mergedRenderRest === 'function' + ? mergedRenderRest(omittedItems.value) + : mergedRenderRest, + }} + > ); } else if (renderRawRest) { - restNode = ( + restNode = () => ( ( - {suffix} - + v-slots={{ default: () => suffix }} + > )} ); // 使用 disabled 避免结构不一致 导致子组件 rerender return ( - - {overflowNode} - + ); }; }, diff --git a/components/vc-overflow/RawItem.tsx b/components/vc-overflow/RawItem.tsx index 65a5c1115..f26a65032 100644 --- a/components/vc-overflow/RawItem.tsx +++ b/components/vc-overflow/RawItem.tsx @@ -35,9 +35,8 @@ export default defineComponent({ {...restContext} {...restProps} {...props} - > - {slots.default?.()} - + v-slots={slots} + > ); };