vue3.2/Vite/Ts93: 菜单权限业务实现
·
Yin灏
路由拆分
src/router/routes.ts
//...
// 常量路由
// 所有角色都包含的路由
export const constantRoute = [
{
//...
},
//...
];
// 异步路由
// 局部角色包含的路由
export const asyncRoute = [
{
//...
},
//...
];
// 任意路由
// 404
export const anyRoute = [
{
//...
},
];
用户小仓库
src/store/modules/user.ts
//...
import { contantRoute, asyncRoute, anyRoute } from "@/router/routes";
import { userInfoResponseData } from "@/api/user/type";
//@ts-ignore
// 按需引入
import cloneDeep from "lodash/cloneDeep";
// 引入路由器对象
import router from "@/router";
//...
const filterAsyncRoute = (asyncRoute: any, routes: any) => {
return asyncRoute.filter((item: any) => {
if (routes.includes(item.name)) {
if (item.children && item.children.length) {
// 这里需要处理,不然会影响原数组(深拷贝问题)
item.chidlren = filterAsyncRoute(item.children, routes);
}
return true;
}
});
};
//...
let useUserStore = defineStore("User", {
state: (): UserState => {
return {
//...
// 将路由对象挂载到用户小仓库
menuRoutes: contantRoute,
};
},
actions: {
//...
// 获取用户信息
async userInfo() {
const result: userInfoResponseData = await reqUserInfo();
if (result.code === 200) {
//...
// 过滤路由
let userAsyncRoute = filterAsyncRoute(
cloneDeep(asyncRoute),
result.data.routes
);
this.menuRoutes = [...contantRoute, ...userAsyncRoute, ...anyRoute];
// 动态追加异步和任意路由
[...userAsyncRoute, ...anyRoute].forEach((route: any) => {
router.addRoute(route);
});
// 打印当前用户全部的路由
console.log(router.getRoutes());
return "ok";
} else {
return Promise.reject(new Error(result.message));
}
},
},
});
解决异步路由刷新白屏问题
src/permisstion.ts
import nprogress from "nprogress";
import "nprogress/nprogress.css";
nprogress.configure({ showSpinner: false });
import router from "@/router";
import pinia from "./store";
import useUserStore from "./store/modules/user";
let userStore = useUserStore(pinia);
import setting from "./setting";
router.beforeEach(async (to: any, from: any, next: any) => {
document.title = setting.title + "-" + to.meta.title;
nprogress.start();
let token = userStore.token;
let username = userStore.username;
if (token) {
if (to.path === "/login") {
next({
path: "/",
});
} else {
if (username) {
next();
} else {
try {
await userStore.userInfo();
// 处理的这里
// 用于在导航守卫中完成一些异步操作后,重新尝试导航
next({ ...to });
} catch (err) {
userStore.userLogout();
next({
path: "/login",
query: {
redirect: to.path,
},
});
}
}
}
} else {
if (to.path === "/login") {
next();
} else {
next({
path: "/login",
query: {
redirect: to.path,
},
});
}
}
});
router.afterEach((to: any, from: any) => {
nprogress.done();
});