123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- <template>
- <Menu
- :selectedKeys="selectedKeys"
- :defaultSelectedKeys="defaultSelectedKeys"
- :mode="mode"
- :openKeys="getOpenKeys"
- :inlineIndent="inlineIndent"
- :theme="theme"
- @open-change="handleOpenChange"
- :class="getMenuClass"
- @click="handleMenuClick"
- :subMenuOpenDelay="0.2"
- v-bind="getInlineCollapseOptions"
- >
- <template v-for="item in items" :key="item.path">
- <BasicSubMenuItem :item="item" :theme="theme" :isHorizontal="isHorizontal" />
- </template>
- </Menu>
- </template>
- <script lang="ts">
- import type { MenuState } from './types';
- import { computed, defineComponent, unref, reactive, watch, toRefs, ref } from 'vue';
- import { Menu } from 'ant-design-vue';
- import BasicSubMenuItem from './components/BasicSubMenuItem.vue';
- import { MenuModeEnum, MenuTypeEnum } from '/@/enums/menuEnum';
- import { useOpenKeys } from './useOpenKeys';
- import { RouteLocationNormalizedLoaded, useRouter } from 'vue-router';
- import { isFunction } from '/@/utils/is';
- import { basicProps } from './props';
- import { useMenuSetting } from '/@/hooks/setting/useMenuSetting';
- import { REDIRECT_NAME } from '/@/router/constant';
- import { useDesign } from '/@/hooks/web/useDesign';
- import { getCurrentParentPath } from '/@/router/menus';
- import { listenerRouteChange } from '/@/logics/mitt/routeChange';
- import { getAllParentPath } from '/@/router/helper/menuHelper';
- export default defineComponent({
- name: 'BasicMenu',
- components: {
- Menu,
- BasicSubMenuItem,
- },
- props: basicProps,
- emits: ['menuClick'],
- setup(props, { emit }) {
- const isClickGo = ref(false);
- const currentActiveMenu = ref('');
- const menuState = reactive<MenuState>({
- defaultSelectedKeys: [],
- openKeys: [],
- selectedKeys: [],
- collapsedOpenKeys: [],
- });
- const { prefixCls } = useDesign('basic-menu');
- const { items, mode, accordion } = toRefs(props);
- const { getCollapsed, getTopMenuAlign, getSplit } = useMenuSetting();
- const { currentRoute } = useRouter();
- const { handleOpenChange, setOpenKeys, getOpenKeys } = useOpenKeys(
- menuState,
- items,
- mode as any,
- accordion,
- );
- const getIsTopMenu = computed(() => {
- const { type, mode } = props;
- return (
- (type === MenuTypeEnum.TOP_MENU && mode === MenuModeEnum.HORIZONTAL) ||
- (props.isHorizontal && unref(getSplit))
- );
- });
- const getMenuClass = computed(() => {
- const align = props.isHorizontal && unref(getSplit) ? 'start' : unref(getTopMenuAlign);
- return [
- prefixCls,
- `justify-${align}`,
- {
- [`${prefixCls}__second`]: !props.isHorizontal && unref(getSplit),
- [`${prefixCls}__sidebar-hor`]: unref(getIsTopMenu),
- },
- ];
- });
- const getInlineCollapseOptions = computed(() => {
- const isInline = props.mode === MenuModeEnum.INLINE;
- const inlineCollapseOptions: { inlineCollapsed?: boolean } = {};
- if (isInline) {
- inlineCollapseOptions.inlineCollapsed = props.mixSider ? false : unref(getCollapsed);
- }
- return inlineCollapseOptions;
- });
- listenerRouteChange((route) => {
- if (route.name === REDIRECT_NAME) return;
- handleMenuChange(route);
- currentActiveMenu.value = route.meta?.currentActiveMenu as string;
- if (unref(currentActiveMenu)) {
- menuState.selectedKeys = [unref(currentActiveMenu)];
- setOpenKeys(unref(currentActiveMenu));
- }
- });
- !props.mixSider &&
- watch(
- () => props.items,
- () => {
- handleMenuChange();
- },
- );
- async function handleMenuClick({ key }: { key: string; keyPath: string[] }) {
- const { beforeClickFn } = props;
- if (beforeClickFn && isFunction(beforeClickFn)) {
- const flag = await beforeClickFn(key);
- if (!flag) return;
- }
- emit('menuClick', key);
- isClickGo.value = true;
- menuState.selectedKeys = [key];
- }
- async function handleMenuChange(route?: RouteLocationNormalizedLoaded) {
- if (unref(isClickGo)) {
- isClickGo.value = false;
- return;
- }
- const path =
- (route || unref(currentRoute)).meta?.currentActiveMenu ||
- (route || unref(currentRoute)).path;
- setOpenKeys(path);
- if (unref(currentActiveMenu)) return;
- if (props.isHorizontal && unref(getSplit)) {
- const parentPath = await getCurrentParentPath(path);
- menuState.selectedKeys = [parentPath];
- } else {
- const parentPaths = await getAllParentPath(props.items, path);
- menuState.selectedKeys = parentPaths;
- }
- }
- return {
- handleMenuClick,
- getInlineCollapseOptions,
- getMenuClass,
- handleOpenChange,
- getOpenKeys,
- ...toRefs(menuState),
- };
- },
- });
- </script>
- <style lang="less">
- @import './index.less';
- </style>
|