mirror of
https://github.com/Tencent/tdesign-vue-next-starter.git
synced 2024-11-10 10:38:23 +08:00
优化菜单选中判断逻辑 (#132)
This commit is contained in:
parent
33bdd29561
commit
09c6b17b7e
|
@ -65,8 +65,9 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { PropType, computed } from 'vue';
|
import { PropType, computed } from 'vue';
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { useSettingStore } from '@/store';
|
import { useSettingStore } from '@/store';
|
||||||
|
import { getActive } from '@/router';
|
||||||
import { prefix } from '@/config/global';
|
import { prefix } from '@/config/global';
|
||||||
import tLogoFull from '@/assets/assets-logo-full.svg?component';
|
import tLogoFull from '@/assets/assets-logo-full.svg?component';
|
||||||
import { MenuRoute } from '@/interface';
|
import { MenuRoute } from '@/interface';
|
||||||
|
@ -115,18 +116,7 @@ const toggleSettingPanel = () => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const active = computed(() => {
|
const active = computed(() => getActive());
|
||||||
const { layout } = props;
|
|
||||||
const route = useRoute();
|
|
||||||
if (!route.path) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return route.path
|
|
||||||
.split('/')
|
|
||||||
.filter((item, index) => index < props.maxLevel - (layout === 'mix' ? 1 : -1) && index > 0)
|
|
||||||
.map((item) => `/${item}`)
|
|
||||||
.join('');
|
|
||||||
});
|
|
||||||
|
|
||||||
const layoutCls = computed(() => [`${prefix}-header-layout`]);
|
const layoutCls = computed(() => [`${prefix}-header-layout`]);
|
||||||
|
|
||||||
|
|
30
src/layouts/components/MenuContent.tsx
Normal file → Executable file
30
src/layouts/components/MenuContent.tsx
Normal file → Executable file
|
@ -1,6 +1,7 @@
|
||||||
import { defineComponent, PropType, computed, h } from 'vue';
|
import { defineComponent, PropType, computed, h } from 'vue';
|
||||||
import { prefix } from '@/config/global';
|
import { prefix } from '@/config/global';
|
||||||
import { MenuRoute } from '@/interface';
|
import { MenuRoute } from '@/interface';
|
||||||
|
import { getActive } from '@/router';
|
||||||
|
|
||||||
const getMenuList = (list: MenuRoute[], basePath?: string): MenuRoute[] => {
|
const getMenuList = (list: MenuRoute[], basePath?: string): MenuRoute[] => {
|
||||||
if (!list) {
|
if (!list) {
|
||||||
|
@ -34,36 +35,33 @@ const renderIcon = (item) => {
|
||||||
return () => '';
|
return () => '';
|
||||||
};
|
};
|
||||||
|
|
||||||
const useRenderNav = (list: Array<MenuRoute>) => {
|
const getPath = (active, item) => {
|
||||||
|
if (active.startsWith(item.path)) {
|
||||||
|
return active;
|
||||||
|
}
|
||||||
|
return item.meta?.single ? item.redirect : item.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
const useRenderNav = (active: string, list: Array<MenuRoute>) => {
|
||||||
return list.map((item) => {
|
return list.map((item) => {
|
||||||
if (!item.children || !item.children.length || item.meta?.single) {
|
if (!item.children || !item.children.length || item.meta?.single) {
|
||||||
const href = item.path.match(/(http|https):\/\/([\w.]+\/?)\S*/);
|
const href = item.path.match(/(http|https):\/\/([\w.]+\/?)\S*/);
|
||||||
if (href) {
|
if (href) {
|
||||||
return (
|
return (
|
||||||
<t-menu-item
|
<t-menu-item href={href?.[0]} name={item.path} value={getPath(active, item)} icon={renderIcon(item)}>
|
||||||
href={href?.[0]}
|
|
||||||
name={item.path}
|
|
||||||
value={item.meta?.single ? item.redirect : item.path}
|
|
||||||
icon={renderIcon(item)}
|
|
||||||
>
|
|
||||||
{item.title}
|
{item.title}
|
||||||
</t-menu-item>
|
</t-menu-item>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<t-menu-item
|
<t-menu-item name={item.path} value={getPath(active, item)} to={item.path} icon={renderIcon(item)}>
|
||||||
name={item.path}
|
|
||||||
value={item.meta?.single ? item.redirect : item.path}
|
|
||||||
to={item.path}
|
|
||||||
icon={renderIcon(item)}
|
|
||||||
>
|
|
||||||
{item.title}
|
{item.title}
|
||||||
</t-menu-item>
|
</t-menu-item>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<t-submenu name={item.path} value={item.path} title={item.title} icon={renderIcon(item)}>
|
<t-submenu name={item.path} value={item.path} title={item.title} icon={renderIcon(item)}>
|
||||||
{item.children && useRenderNav(item.children)}
|
{item.children && useRenderNav(active, item.children)}
|
||||||
</t-submenu>
|
</t-submenu>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -77,6 +75,7 @@ export default defineComponent({
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
const active = computed(() => getActive());
|
||||||
const list = computed(() => {
|
const list = computed(() => {
|
||||||
const { navData } = props;
|
const { navData } = props;
|
||||||
return getMenuList(navData);
|
return getMenuList(navData);
|
||||||
|
@ -84,11 +83,12 @@ export default defineComponent({
|
||||||
|
|
||||||
return {
|
return {
|
||||||
prefix,
|
prefix,
|
||||||
|
active,
|
||||||
list,
|
list,
|
||||||
useRenderNav,
|
useRenderNav,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
return <div>{this.useRenderNav(this.list)}</div>;
|
return <div>{this.useRenderNav(this.active, this.list)}</div>;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,17 +1,20 @@
|
||||||
import { defineComponent, PropType, computed, onMounted } from 'vue';
|
import { defineComponent, PropType, computed, onMounted } from 'vue';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import { prefix } from '@/config/global';
|
import { prefix } from '@/config/global';
|
||||||
import pgk from '../../../package.json';
|
import pgk from '../../../package.json';
|
||||||
import MenuContent from './MenuContent';
|
import MenuContent from './MenuContent';
|
||||||
import tLogo from '@/assets/assets-t-logo.svg?component';
|
import tLogo from '@/assets/assets-t-logo.svg?component';
|
||||||
import tLogoFull from '@/assets/assets-logo-full.svg?component';
|
import tLogoFull from '@/assets/assets-logo-full.svg?component';
|
||||||
import { useSettingStore } from '@/store';
|
import { useSettingStore } from '@/store';
|
||||||
|
import { getActive } from '@/router';
|
||||||
|
|
||||||
const MIN_POINT = 992 - 1;
|
const MIN_POINT = 992 - 1;
|
||||||
|
|
||||||
const useComputed = (props) => {
|
const useComputed = (props) => {
|
||||||
const collapsed = computed(() => useSettingStore().isSidebarCompact);
|
const collapsed = computed(() => useSettingStore().isSidebarCompact);
|
||||||
|
|
||||||
|
const active = computed(() => getActive());
|
||||||
|
|
||||||
const sideNavCls = computed(() => {
|
const sideNavCls = computed(() => {
|
||||||
const { isCompact } = props;
|
const { isCompact } = props;
|
||||||
return [
|
return [
|
||||||
|
@ -40,6 +43,7 @@ const useComputed = (props) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
active,
|
||||||
collapsed,
|
collapsed,
|
||||||
sideNavCls,
|
sideNavCls,
|
||||||
menuCls,
|
menuCls,
|
||||||
|
@ -107,18 +111,6 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const getActiveName = (maxLevel = 2) => {
|
|
||||||
const route = useRoute();
|
|
||||||
if (!route.path) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return route.path
|
|
||||||
.split('/')
|
|
||||||
.filter((_item: string, index: number) => index <= maxLevel && index > 0)
|
|
||||||
.map((item: string) => `/${item}`)
|
|
||||||
.join('');
|
|
||||||
};
|
|
||||||
|
|
||||||
const goHome = () => {
|
const goHome = () => {
|
||||||
router.push('/dashboard/base');
|
router.push('/dashboard/base');
|
||||||
};
|
};
|
||||||
|
@ -128,18 +120,16 @@ export default defineComponent({
|
||||||
...useComputed(props),
|
...useComputed(props),
|
||||||
autoCollapsed,
|
autoCollapsed,
|
||||||
changeCollapsed,
|
changeCollapsed,
|
||||||
getActiveName,
|
|
||||||
goHome,
|
goHome,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
const active = this.getActiveName();
|
|
||||||
return (
|
return (
|
||||||
<div class={this.sideNavCls}>
|
<div class={this.sideNavCls}>
|
||||||
<t-menu
|
<t-menu
|
||||||
class={this.menuCls}
|
class={this.menuCls}
|
||||||
theme={this.theme}
|
theme={this.theme}
|
||||||
value={active}
|
value={this.active}
|
||||||
collapsed={this.collapsed}
|
collapsed={this.collapsed}
|
||||||
v-slots={{
|
v-slots={{
|
||||||
logo: () =>
|
logo: () =>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
|
import { useRoute, createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
|
||||||
|
|
||||||
import baseRouters from './modules/base';
|
import baseRouters from './modules/base';
|
||||||
import componentsRouters from './modules/components';
|
import componentsRouters from './modules/components';
|
||||||
|
@ -30,6 +30,18 @@ const defaultRouterList: Array<RouteRecordRaw> = [
|
||||||
|
|
||||||
export const allRoutes = [...defaultRouterList, ...asyncRouterList];
|
export const allRoutes = [...defaultRouterList, ...asyncRouterList];
|
||||||
|
|
||||||
|
export const getActive = (maxLevel = 2): string => {
|
||||||
|
const route = useRoute();
|
||||||
|
if (!route.path) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return route.path
|
||||||
|
.split('/')
|
||||||
|
.filter((_item: string, index: number) => index <= maxLevel && index > 0)
|
||||||
|
.map((item: string) => `/${item}`)
|
||||||
|
.join('');
|
||||||
|
};
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHashHistory(),
|
history: createWebHashHistory(),
|
||||||
routes: allRoutes,
|
routes: allRoutes,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user