Skip to content

Commit

Permalink
fix: 修复多级路由下切换的报错问题,扁平化为二级路由
Browse files Browse the repository at this point in the history
  • Loading branch information
yuntian001 committed Sep 6, 2022
1 parent bc6c562 commit 9736fb1
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 33 deletions.
20 changes: 17 additions & 3 deletions src/layout/components/header/components/topBar/components/left.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,31 @@
</template>
<script setup lang="ts" name="Left">
import { mitter, event } from '@/event';
import { useSettingStore, useGlobalStore } from '@/store';
import { useSettingStore, useGlobalStore, useRouteStore } from '@/store';
import { RouteLocationNormalized, RouteRecordRaw } from 'vue-router';
const { themeConfig } = useSettingStore();
const globalStore = useGlobalStore();
const setMenuCollapse = () => {
themeConfig.menuCollapse = !themeConfig.menuCollapse;
};
const breadcrumbList = ref([] as RouteRecordRaw[]);
const breadcrumbList = ref([] as Pick<RouteRecordRaw, 'name' | 'path' | 'meta' | 'redirect'>[]);
const route = useRoute();
const { routes } = useRouteStore();
const setBreadcrumbList = (route: RouteLocationNormalized) => {
breadcrumbList.value = route.matched.filter((item) => item.meta && item.meta.title && item.meta.breadcrumb !== false);
const list = [] as Pick<RouteRecordRaw, 'name' | 'path' | 'meta' | 'redirect'>[];
let temp = { children: routes } as unknown as RouteRecordRaw;
route.meta.menuIndex!.forEach((item) => {
temp = temp.children![item];
if (temp.meta && temp.meta.title && temp.meta.breadcrumb !== false) {
list.push({
name: temp.name,
path: temp.path,
meta: temp.meta,
redirect: temp.redirect === route.path ? undefined : temp.redirect,
});
}
});
breadcrumbList.value = list;
};
setBreadcrumbList(route);
mitter.on(event.BEFORE_ROUTE_CHANGE, ({ to }) => setBreadcrumbList(to), true);
Expand Down
30 changes: 6 additions & 24 deletions src/layout/components/menu/components/menuItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,35 @@
<component
:is="onlyOneChild.meta?.isLink ? 'a' : 'routerLink'"
v-if="onlyOneChild.meta && onlyOneChild.meta.title"
:href="basePath"
:to="resolvePath(onlyOneChild.path)"
:href="onlyOneChild.path"
:to="onlyOneChild.path"
>
<el-menu-item :index="resolvePath(onlyOneChild.path)" :title="$t(onlyOneChild.meta.title)">
<el-menu-item :index="onlyOneChild.path" :title="$t(onlyOneChild.meta.title)">
<component :is="onlyOneChild.meta.icon" v-if="onlyOneChild.meta.icon" />
<template #title>
<span class="menu">{{ $t(onlyOneChild.meta.title) }}</span>
</template>
</el-menu-item>
</component>
</template>
<el-sub-menu v-else :index="resolvePath(item.path)">
<el-sub-menu v-else :index="item.path">
<template v-if="item.meta" #title>
<component :is="item.meta!.icon" v-if="item.meta!.icon" />
<span class="menu">{{ $t(item.meta!.title!) }}</span>
</template>
<layout-menu-item
v-for="child in item.children"
:key="child.path"
:item="child"
:base-path="resolvePath(child.path)"
></layout-menu-item>
<layout-menu-item v-for="child in item.children" :key="child.path" :item="child"></layout-menu-item>
</el-sub-menu>
</template>
</template>
<script setup lang="ts" name="MenuItem">
import { isExternal } from '@/utils/validate';
import { resolve } from 'path-browserify';
import { PropType } from 'vue';
import { RouteRecordRaw } from 'vue-router';
const props = defineProps({
item: {
type: Object as PropType<RouteRecordRaw>,
required: true,
},
basePath: {
// 当前菜单的绝对路径
type: String,
default: '',
},
});
let onlyOneChild = ref<RouteRecordRaw>();
const hasOneShowingChild = (children = [] as RouteRecordRaw[], parent: RouteRecordRaw) => {
Expand All @@ -56,16 +44,10 @@ const hasOneShowingChild = (children = [] as RouteRecordRaw[], parent: RouteReco
return true;
}
if (showingChildren.length === 0) {
onlyOneChild.value = { ...parent, path: '', noShowingChildren: true };
onlyOneChild.value = { ...parent, noShowingChildren: true };
return true;
}
return false;
};
const resolvePath = (routePath: string) => {
if (isExternal(routePath) || isExternal(props.basePath)) {
return routePath;
}
return resolve(props.basePath, routePath);
};
hasOneShowingChild(props.item.children, props.item);
</script>
2 changes: 1 addition & 1 deletion src/layout/components/menu/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
:collapse="!globalStore.isMobile && themeConfig.menuCollapse"
>
<div class="title">M<span>e - Admin</span></div>
<layout-menu-item v-for="route in routeStore.routes" :key="route.path" :item="route" :base-path="route.path" />
<layout-menu-item v-for="route in routeStore.routes" :key="route.path" :item="route" />
</el-menu>
</el-scrollbar>
</template>
Expand Down
54 changes: 53 additions & 1 deletion src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import Layout from '@/layout/index.vue';
export const asyncRoutes = concatObjectValue<RouteRecordRaw>(
import.meta.glob('./routes/*.ts', { eager: true, import: 'routes' }),
);
import { isExternal } from '@/utils/validate';
import { resolve } from 'path-browserify';

export const constantRoutes: RouteRecordRaw[] = [
{
path: '/',
Expand Down Expand Up @@ -46,9 +49,58 @@ export const constantRoutes: RouteRecordRaw[] = [
meta: { hideMenu: true, title: '404' },
},
];

//路由地址转为绝对地址
export const resolvePath = (routePath: string, basePath = '') => {
if (isExternal(routePath) || isExternal(basePath)) {
return routePath;
}
return resolve(basePath, routePath);
};

//扁平化路由
export const flatteningRoutes = (
routes: RouteRecordRaw[],
basePath = '',
menuIndex: number[] = [],
newRoutes: RouteRecordRaw[] = [],
) => {
routes.forEach((route, index) => {
route.path = resolvePath(route.path, basePath);
if (!route.meta) {
route.meta = { title: '' };
}
route.meta.menuIndex = [...menuIndex, index];
newRoutes.push(Object.assign({ ...route }, { children: [] }));
if (route.children) {
flatteningRoutes(route.children, route.path, route.meta.menuIndex, newRoutes);
}
});
return newRoutes;
};
//扁平化为2级路由
export const flatteningRoutes2 = (routes: RouteRecordRaw[], startIndex = 0) => {
const newRoutes = [] as RouteRecordRaw[];
routes.forEach((route, index) => {
if (!route.meta) {
route.meta = { title: '' };
}
route.meta.menuIndex = [index + startIndex];
newRoutes.push(
Object.assign(
{ ...route },
{
children: route.children ? flatteningRoutes(route.children, route.path, [index + startIndex]) : [],
},
),
);
});
return newRoutes;
};

export const router = createRouter({
history: createWebHashHistory(), //createWebHistory(),
routes: constantRoutes,
routes: flatteningRoutes2(constantRoutes),
});

/**
Expand Down
1 change: 1 addition & 0 deletions src/router/routes/example/multilevel/1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const routes: RouteRecordRaw[] = [
path: '1-1',
component: LayoutPage,
meta: { title: '多级菜单1-1', alwaysShow: true },
redirect: '/example/multilevel/1/1-1/1-1-1',
children: [
{
path: '1-1-1',
Expand Down
8 changes: 4 additions & 4 deletions src/store/modules/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { loginConfig as config } from '@/config';
import { loading } from '@/utils/loading';
import { PageEnum } from '@/enums/pageEnum';
import { loginApi, LoginParams, userInfoApi, UserInfoResult } from '@/api/user';
import { router } from '@/router';
import { router, flatteningRoutes2, constantRoutes } from '@/router';
import useRouteStore from './route';
interface UserState {
user: UserInfoResult; // 用户信息
Expand Down Expand Up @@ -52,9 +52,9 @@ export default defineStore({
this.token = token;
this.user = await userInfoApi(true)();
this.rules = this.user.rules;
useRouteStore()
.generateRoutes()
.forEach((route) => router.addRoute(route));
flatteningRoutes2(useRouteStore().generateRoutes(), constantRoutes.length).forEach((route) =>
router.addRoute(route),
);
} else {
this.token = '';
}
Expand Down
2 changes: 2 additions & 0 deletions types/vue-router.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ declare module 'vue-router' {
alwaysShow?: boolean;
// 是否需要面包屑false不需要 ture或undefined为需要
breadcrumb?: boolean;
//路由在菜单的index deep映射(会动态计算不要设置默认值)
menuIndex?: number[];
}
export interface _RouteRecordBase {
// 没有需要展示的子集(会动态计算不要设置默认值)
Expand Down

0 comments on commit 9736fb1

Please sign in to comment.