refactor: menu
parent
8862f604e2
commit
6bf3d283f6
|
@ -14,7 +14,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
const fixedMode: MenuMode = 'inline';
|
const fixedMode: MenuMode = 'inline';
|
||||||
const { forceSubMenuRender, motion, mode, defaultMotions } = useInjectMenu();
|
const { motion, mode, defaultMotions } = useInjectMenu();
|
||||||
const sameModeRef = computed(() => mode.value === fixedMode);
|
const sameModeRef = computed(() => mode.value === fixedMode);
|
||||||
const destroy = ref(!sameModeRef.value);
|
const destroy = ref(!sameModeRef.value);
|
||||||
|
|
||||||
|
|
|
@ -87,8 +87,12 @@ export default defineComponent({
|
||||||
mouseLeaveDelay={subMenuCloseDelay.value}
|
mouseLeaveDelay={subMenuCloseDelay.value}
|
||||||
onPopupVisibleChange={onVisibleChange}
|
onPopupVisibleChange={onVisibleChange}
|
||||||
// forceRender={forceSubMenuRender}
|
// forceRender={forceSubMenuRender}
|
||||||
// popupMotion={mergedMotion}
|
v-slots={{
|
||||||
v-slots={{ popup: slots.popup, default: slots.default }}
|
popup: () => {
|
||||||
|
return slots.popup?.({ visible: innerVisible.value });
|
||||||
|
},
|
||||||
|
default: slots.default,
|
||||||
|
}}
|
||||||
></Trigger>
|
></Trigger>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,6 +16,7 @@ import useDirectionStyle from './hooks/useDirectionStyle';
|
||||||
import PopupTrigger from './PopupTrigger';
|
import PopupTrigger from './PopupTrigger';
|
||||||
import SubMenuList from './SubMenuList';
|
import SubMenuList from './SubMenuList';
|
||||||
import InlineSubMenuList from './InlineSubMenuList';
|
import InlineSubMenuList from './InlineSubMenuList';
|
||||||
|
import Transition, { getTransitionProps } from 'ant-design-vue/es/_util/transition';
|
||||||
|
|
||||||
let indexGuid = 0;
|
let indexGuid = 0;
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
@ -75,6 +76,8 @@ export default defineComponent({
|
||||||
registerMenuInfo,
|
registerMenuInfo,
|
||||||
unRegisterMenuInfo,
|
unRegisterMenuInfo,
|
||||||
selectedSubMenuEventKeys,
|
selectedSubMenuEventKeys,
|
||||||
|
motion,
|
||||||
|
defaultMotions,
|
||||||
} = useInjectMenu();
|
} = useInjectMenu();
|
||||||
|
|
||||||
registerMenuInfo(eventKey, menuInfo);
|
registerMenuInfo(eventKey, menuInfo);
|
||||||
|
@ -227,7 +230,13 @@ export default defineComponent({
|
||||||
|
|
||||||
if (!overflowDisabled.value) {
|
if (!overflowDisabled.value) {
|
||||||
const triggerMode = triggerModeRef.value;
|
const triggerMode = triggerModeRef.value;
|
||||||
|
const style = ref({});
|
||||||
|
const className = ref('');
|
||||||
|
const mergedMotion = computed(() => {
|
||||||
|
const m = motion.value || defaultMotions.value?.[mode.value];
|
||||||
|
const res = typeof m === 'function' ? m(style, className) : m;
|
||||||
|
return res ? getTransitionProps(res.name) : undefined;
|
||||||
|
});
|
||||||
titleNode = (
|
titleNode = (
|
||||||
<PopupTrigger
|
<PopupTrigger
|
||||||
mode={triggerMode}
|
mode={triggerMode}
|
||||||
|
@ -238,11 +247,13 @@ export default defineComponent({
|
||||||
disabled={mergedDisabled.value}
|
disabled={mergedDisabled.value}
|
||||||
onVisibleChange={onPopupVisibleChange}
|
onVisibleChange={onPopupVisibleChange}
|
||||||
v-slots={{
|
v-slots={{
|
||||||
popup: () => (
|
popup: ({ visible }) => (
|
||||||
<MenuContextProvider props={{ mode: triggerModeRef }}>
|
<MenuContextProvider props={{ mode: triggerModeRef }}>
|
||||||
<SubMenuList id={popupId} ref={popupRef}>
|
<Transition {...mergedMotion.value}>
|
||||||
{slots.default?.()}
|
<SubMenuList v-show={visible} id={popupId} ref={popupRef}>
|
||||||
</SubMenuList>
|
{slots.default?.()}
|
||||||
|
</SubMenuList>
|
||||||
|
</Transition>
|
||||||
</MenuContextProvider>
|
</MenuContextProvider>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
|
|
125
examples/App.vue
125
examples/App.vue
|
@ -1,49 +1,100 @@
|
||||||
<template>
|
<template>
|
||||||
<a-menu v-model:selectedKeys="current" mode="horizontal">
|
<div style="width: 256px">
|
||||||
<a-menu-item key="mail">
|
<a-button type="primary" style="margin-bottom: 16px" @click="toggleCollapsed">
|
||||||
<mail-outlined />
|
<MenuUnfoldOutlined v-if="collapsed" />
|
||||||
Navigation One
|
<MenuFoldOutlined v-else />
|
||||||
</a-menu-item>
|
</a-button>
|
||||||
<a-menu-item key="app" disabled>
|
<a-menu
|
||||||
<appstore-outlined />
|
v-model:openKeys="openKeys"
|
||||||
Navigation Two
|
v-model:selectedKeys="selectedKeys"
|
||||||
</a-menu-item>
|
mode="inline"
|
||||||
<a-sub-menu>
|
theme="dark"
|
||||||
<template #title>
|
:inline-collapsed="collapsed"
|
||||||
<span class="submenu-title-wrapper">
|
>
|
||||||
<setting-outlined />
|
<a-menu-item key="1">
|
||||||
Navigation Three - Submenu
|
<PieChartOutlined />
|
||||||
</span>
|
<span>Option 1</span>
|
||||||
</template>
|
</a-menu-item>
|
||||||
<a-menu-item-group title="Item 1">
|
<a-menu-item key="2">
|
||||||
<a-menu-item key="setting:1">Option 1</a-menu-item>
|
<DesktopOutlined />
|
||||||
<a-menu-item key="setting:2">Option 2</a-menu-item>
|
<span>Option 2</span>
|
||||||
</a-menu-item-group>
|
</a-menu-item>
|
||||||
<a-menu-item-group title="Item 2">
|
<a-menu-item key="3">
|
||||||
<a-menu-item key="setting:3">Option 3</a-menu-item>
|
<InboxOutlined />
|
||||||
<a-menu-item key="setting:4">Option 4</a-menu-item>
|
<span>Option 3</span>
|
||||||
</a-menu-item-group>
|
</a-menu-item>
|
||||||
</a-sub-menu>
|
<a-sub-menu key="sub1">
|
||||||
<a-menu-item key="alipay">
|
<template #title>
|
||||||
<a href="https://antdv.com" target="_blank" rel="noopener noreferrer">
|
<span>
|
||||||
Navigation Four - Link
|
<MailOutlined />
|
||||||
</a>
|
<span>Navigation One</span>
|
||||||
</a-menu-item>
|
</span>
|
||||||
</a-menu>
|
</template>
|
||||||
|
<a-menu-item key="5">Option 5</a-menu-item>
|
||||||
|
<a-menu-item key="6">Option 6</a-menu-item>
|
||||||
|
<a-menu-item key="7">Option 7</a-menu-item>
|
||||||
|
<a-menu-item key="8">Option 8</a-menu-item>
|
||||||
|
</a-sub-menu>
|
||||||
|
<a-sub-menu key="sub2">
|
||||||
|
<template #title>
|
||||||
|
<span>
|
||||||
|
<AppstoreOutlined />
|
||||||
|
<span>Navigation Two</span>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
<a-menu-item key="9">Option 9</a-menu-item>
|
||||||
|
<a-menu-item key="10">Option 10</a-menu-item>
|
||||||
|
<a-sub-menu key="sub3" title="Submenu">
|
||||||
|
<a-menu-item key="11">Option 11</a-menu-item>
|
||||||
|
<a-menu-item key="12">Option 12</a-menu-item>
|
||||||
|
</a-sub-menu>
|
||||||
|
</a-sub-menu>
|
||||||
|
</a-menu>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script lang="ts">
|
||||||
import { defineComponent, ref } from 'vue';
|
import { defineComponent, reactive, toRefs, watch } from 'vue';
|
||||||
import { MailOutlined, AppstoreOutlined, SettingOutlined } from '@ant-design/icons-vue';
|
import {
|
||||||
|
MenuFoldOutlined,
|
||||||
|
MenuUnfoldOutlined,
|
||||||
|
PieChartOutlined,
|
||||||
|
MailOutlined,
|
||||||
|
DesktopOutlined,
|
||||||
|
InboxOutlined,
|
||||||
|
AppstoreOutlined,
|
||||||
|
} from '@ant-design/icons-vue';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
MenuFoldOutlined,
|
||||||
|
MenuUnfoldOutlined,
|
||||||
|
PieChartOutlined,
|
||||||
MailOutlined,
|
MailOutlined,
|
||||||
|
DesktopOutlined,
|
||||||
|
InboxOutlined,
|
||||||
AppstoreOutlined,
|
AppstoreOutlined,
|
||||||
SettingOutlined,
|
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
const current = ref(['mail']);
|
const state = reactive({
|
||||||
|
collapsed: false,
|
||||||
|
selectedKeys: ['1'],
|
||||||
|
openKeys: ['sub1'],
|
||||||
|
preOpenKeys: ['sub1'],
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => state.openKeys,
|
||||||
|
(val, oldVal) => {
|
||||||
|
state.preOpenKeys = oldVal;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
const toggleCollapsed = () => {
|
||||||
|
state.collapsed = !state.collapsed;
|
||||||
|
state.openKeys = state.collapsed ? [] : state.preOpenKeys;
|
||||||
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
current,
|
...toRefs(state),
|
||||||
|
toggleCollapsed,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue