perf: update menu

pull/4459/head
tangjinzhou 3 years ago
parent 5bdd6f4007
commit 386f3d003f

@ -1,4 +1,5 @@
import { PropType, ExtractPropTypes, ComputedRef, watch } from 'vue'; import type { PropType, ExtractPropTypes, ComputedRef } from 'vue';
import { watch } from 'vue';
import { defineComponent, computed, nextTick, ref, watchEffect, onBeforeUnmount } from 'vue'; import { defineComponent, computed, nextTick, ref, watchEffect, onBeforeUnmount } from 'vue';
import cloneDeep from 'lodash-es/cloneDeep'; import cloneDeep from 'lodash-es/cloneDeep';
import PropTypes from '../_util/vue-types'; import PropTypes from '../_util/vue-types';

@ -1,6 +1,7 @@
import { computed, defineComponent, ref, watch } from 'vue'; import { computed, defineComponent, ref, watch } from 'vue';
import Transition from '../../_util/transition'; import Transition from '../../_util/transition';
import { useInjectMenu, MenuContextProvider } from './hooks/useMenuContext'; import { useInjectMenu, MenuContextProvider } from './hooks/useMenuContext';
import type { MenuMode } from './interface';
import SubMenuList from './SubMenuList'; import SubMenuList from './SubMenuList';
export default defineComponent({ export default defineComponent({
@ -12,7 +13,7 @@ export default defineComponent({
keyPath: Array, keyPath: Array,
}, },
setup(props, { slots }) { setup(props, { slots }) {
const fixedMode = computed(() => 'inline'); const fixedMode = computed<MenuMode>(() => 'inline');
const { motion, mode, defaultMotions } = useInjectMenu(); const { motion, mode, defaultMotions } = useInjectMenu();
const sameModeRef = computed(() => mode.value === fixedMode.value); const sameModeRef = computed(() => mode.value === fixedMode.value);
const destroy = ref(!sameModeRef.value); const destroy = ref(!sameModeRef.value);
@ -43,12 +44,7 @@ export default defineComponent({
return null; return null;
} }
return ( return (
<MenuContextProvider <MenuContextProvider mode={fixedMode.value}>
props={{
mode: fixedMode,
locked: !sameModeRef.value,
}}
>
<Transition {...mergedMotion.value}> <Transition {...mergedMotion.value}>
<SubMenuList <SubMenuList
v-show={mergedOpen.value} v-show={mergedOpen.value}

@ -367,7 +367,7 @@ export default defineComponent({
siderCollapsed, siderCollapsed,
defaultMotions: computed(() => (isMounted.value ? defaultMotions : null)), defaultMotions: computed(() => (isMounted.value ? defaultMotions : null)),
motion: computed(() => (isMounted.value ? props.motion : null)), motion: computed(() => (isMounted.value ? props.motion : null)),
overflowDisabled: computed(() => undefined), overflowDisabled: ref(undefined),
onOpenChange: onInternalOpenChange, onOpenChange: onInternalOpenChange,
onItemClick: onInternalClick, onItemClick: onInternalClick,
registerMenuInfo, registerMenuInfo,
@ -391,7 +391,7 @@ export default defineComponent({
// Always wrap provider to avoid sub node re-mount // Always wrap provider to avoid sub node re-mount
<MenuContextProvider <MenuContextProvider
key={child.key} key={child.key}
props={{ overflowDisabled: computed(() => index > lastVisibleIndex.value) }} overflowDisabled={index > lastVisibleIndex.value}
> >
{child} {child}
</MenuContextProvider> </MenuContextProvider>

@ -268,12 +268,7 @@ export default defineComponent({
onVisibleChange={onPopupVisibleChange} onVisibleChange={onPopupVisibleChange}
v-slots={{ v-slots={{
popup: ({ visible }) => ( popup: ({ visible }) => (
<MenuContextProvider <MenuContextProvider mode={subMenuTriggerModeRef.value} isRootMenu={false}>
props={{
mode: subMenuTriggerModeRef,
isRootMenu: false,
}}
>
<Transition {...mergedMotion.value}> <Transition {...mergedMotion.value}>
<SubMenuList v-show={visible} id={popupId} ref={popupRef}> <SubMenuList v-show={visible} id={popupId} ref={popupRef}>
{slots.default?.()} {slots.default?.()}
@ -292,7 +287,7 @@ export default defineComponent({
titleNode = <PopupTrigger>{titleNode}</PopupTrigger>; titleNode = <PopupTrigger>{titleNode}</PopupTrigger>;
} }
return ( return (
<MenuContextProvider props={{ mode: renderMode }}> <MenuContextProvider mode={renderMode.value}>
<Overflow.Item <Overflow.Item
component="li" component="li"
{...attrs} {...attrs}

@ -1,5 +1,7 @@
import type { Key } from '../../../_util/type'; import type { Key } from '../../../_util/type';
import type { ComputedRef, CSSProperties, InjectionKey, Ref, UnwrapRef } from 'vue'; import type { ComputedRef, CSSProperties, InjectionKey, PropType, Ref, UnwrapRef } from 'vue';
import { toRef } from 'vue';
import { watchEffect } from 'vue';
import { defineComponent, inject, provide } from 'vue'; import { defineComponent, inject, provide } from 'vue';
import type { import type {
BuiltinPlacements, BuiltinPlacements,
@ -31,8 +33,6 @@ export interface MenuContextProps {
selectedSubMenuEventKeys: Ref<string[]>; selectedSubMenuEventKeys: Ref<string[]>;
rtl?: ComputedRef<boolean>; rtl?: ComputedRef<boolean>;
locked?: Ref<boolean>;
inlineCollapsed: Ref<boolean>; inlineCollapsed: Ref<boolean>;
antdMenuTheme?: ComputedRef<MenuTheme>; antdMenuTheme?: ComputedRef<MenuTheme>;
@ -44,7 +44,7 @@ export interface MenuContextProps {
// // Disabled // // Disabled
disabled?: ComputedRef<boolean>; disabled?: ComputedRef<boolean>;
// // Used for overflow only. Prevent hidden node trigger open // // Used for overflow only. Prevent hidden node trigger open
overflowDisabled?: ComputedRef<boolean>; overflowDisabled?: Ref<boolean>;
// // Active // // Active
activeKeys: Ref<Key[]>; activeKeys: Ref<Key[]>;
@ -108,10 +108,25 @@ const MenuContextProvider = defineComponent({
name: 'MenuContextProvider', name: 'MenuContextProvider',
inheritAttrs: false, inheritAttrs: false,
props: { props: {
props: Object, mode: { type: String as PropType<MenuMode>, default: undefined },
overflowDisabled: { type: Boolean, default: undefined },
isRootMenu: { type: Boolean, default: undefined },
}, },
setup(props, { slots }) { setup(props, { slots }) {
useProvideMenu({ ...useInjectMenu(), ...props.props }); const menuContext = useInjectMenu();
const newContext = { ...menuContext };
watchEffect(() => {
if (props.mode !== undefined) {
newContext.mode = toRef(props, 'mode');
}
if (props.isRootMenu !== undefined) {
newContext.isRootMenu = props.isRootMenu;
}
if (props.overflowDisabled !== undefined) {
newContext.overflowDisabled = toRef(props, 'overflowDisabled');
}
});
useProvideMenu(newContext);
return () => slots.default?.(); return () => slots.default?.();
}, },
}); });

Loading…
Cancel
Save