refactor: menu

feat-new-menu
tanjinzhou 2021-05-20 16:05:24 +08:00
parent 8862f604e2
commit 6bf3d283f6
4 changed files with 111 additions and 45 deletions

View File

@ -14,7 +14,7 @@ export default defineComponent({
},
setup(props, { slots }) {
const fixedMode: MenuMode = 'inline';
const { forceSubMenuRender, motion, mode, defaultMotions } = useInjectMenu();
const { motion, mode, defaultMotions } = useInjectMenu();
const sameModeRef = computed(() => mode.value === fixedMode);
const destroy = ref(!sameModeRef.value);

View File

@ -87,8 +87,12 @@ export default defineComponent({
mouseLeaveDelay={subMenuCloseDelay.value}
onPopupVisibleChange={onVisibleChange}
// forceRender={forceSubMenuRender}
// popupMotion={mergedMotion}
v-slots={{ popup: slots.popup, default: slots.default }}
v-slots={{
popup: () => {
return slots.popup?.({ visible: innerVisible.value });
},
default: slots.default,
}}
></Trigger>
);
};

View File

@ -16,6 +16,7 @@ import useDirectionStyle from './hooks/useDirectionStyle';
import PopupTrigger from './PopupTrigger';
import SubMenuList from './SubMenuList';
import InlineSubMenuList from './InlineSubMenuList';
import Transition, { getTransitionProps } from 'ant-design-vue/es/_util/transition';
let indexGuid = 0;
export default defineComponent({
@ -75,6 +76,8 @@ export default defineComponent({
registerMenuInfo,
unRegisterMenuInfo,
selectedSubMenuEventKeys,
motion,
defaultMotions,
} = useInjectMenu();
registerMenuInfo(eventKey, menuInfo);
@ -227,7 +230,13 @@ export default defineComponent({
if (!overflowDisabled.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 = (
<PopupTrigger
mode={triggerMode}
@ -238,11 +247,13 @@ export default defineComponent({
disabled={mergedDisabled.value}
onVisibleChange={onPopupVisibleChange}
v-slots={{
popup: () => (
popup: ({ visible }) => (
<MenuContextProvider props={{ mode: triggerModeRef }}>
<SubMenuList id={popupId} ref={popupRef}>
{slots.default?.()}
</SubMenuList>
<Transition {...mergedMotion.value}>
<SubMenuList v-show={visible} id={popupId} ref={popupRef}>
{slots.default?.()}
</SubMenuList>
</Transition>
</MenuContextProvider>
),
}}

View File

@ -1,49 +1,100 @@
<template>
<a-menu v-model:selectedKeys="current" mode="horizontal">
<a-menu-item key="mail">
<mail-outlined />
Navigation One
</a-menu-item>
<a-menu-item key="app" disabled>
<appstore-outlined />
Navigation Two
</a-menu-item>
<a-sub-menu>
<template #title>
<span class="submenu-title-wrapper">
<setting-outlined />
Navigation Three - Submenu
</span>
</template>
<a-menu-item-group title="Item 1">
<a-menu-item key="setting:1">Option 1</a-menu-item>
<a-menu-item key="setting:2">Option 2</a-menu-item>
</a-menu-item-group>
<a-menu-item-group title="Item 2">
<a-menu-item key="setting:3">Option 3</a-menu-item>
<a-menu-item key="setting:4">Option 4</a-menu-item>
</a-menu-item-group>
</a-sub-menu>
<a-menu-item key="alipay">
<a href="https://antdv.com" target="_blank" rel="noopener noreferrer">
Navigation Four - Link
</a>
</a-menu-item>
</a-menu>
<div style="width: 256px">
<a-button type="primary" style="margin-bottom: 16px" @click="toggleCollapsed">
<MenuUnfoldOutlined v-if="collapsed" />
<MenuFoldOutlined v-else />
</a-button>
<a-menu
v-model:openKeys="openKeys"
v-model:selectedKeys="selectedKeys"
mode="inline"
theme="dark"
:inline-collapsed="collapsed"
>
<a-menu-item key="1">
<PieChartOutlined />
<span>Option 1</span>
</a-menu-item>
<a-menu-item key="2">
<DesktopOutlined />
<span>Option 2</span>
</a-menu-item>
<a-menu-item key="3">
<InboxOutlined />
<span>Option 3</span>
</a-menu-item>
<a-sub-menu key="sub1">
<template #title>
<span>
<MailOutlined />
<span>Navigation One</span>
</span>
</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>
<script>
import { defineComponent, ref } from 'vue';
import { MailOutlined, AppstoreOutlined, SettingOutlined } from '@ant-design/icons-vue';
<script lang="ts">
import { defineComponent, reactive, toRefs, watch } from 'vue';
import {
MenuFoldOutlined,
MenuUnfoldOutlined,
PieChartOutlined,
MailOutlined,
DesktopOutlined,
InboxOutlined,
AppstoreOutlined,
} from '@ant-design/icons-vue';
export default defineComponent({
components: {
MenuFoldOutlined,
MenuUnfoldOutlined,
PieChartOutlined,
MailOutlined,
DesktopOutlined,
InboxOutlined,
AppstoreOutlined,
SettingOutlined,
},
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 {
current,
...toRefs(state),
toggleCollapsed,
};
},
});