前言
学无止境,无止境学。大家好,我是张大鹏,之前在抖音有5万多粉丝,不过现在不拍视频,专心写公众号了。笔者目前是高级Python工程师,之前是全栈工程师,主要擅长Golang和Python开发,对于Java,Vue,React也有一些研究。工作之余,喜欢学习和分享,希望能够通过此公众号,将自己学到的东西分享给大家,和大家一起交流,一起成长,一起进步。
根据菜单动态添加路由
之前咱们的路由是在router里面直接写死的,这样是不太合理的。因为每个用户都有自己不同的菜单,我们应该根据不同的用户菜单,生成不同的路由。根据用户信息中的菜单列表,动态的生成该用户拥有的路由。
修改路由器:src/core/router/index.js
import {createRouter, createWebHashHistory} from "vue-router"
// 引入页面
import Layout from "../../pages/layout/index.vue"
import NotFound from "../../pages/404.vue"
import Login from "../../pages/login.vue"
import Index from "../../pages/index.vue"
// 静态路由数组
const routes = [
// 配置单个路由
{
path: "/",
name: "Layout",
component: Layout,
},
// 登录页面
{
path: "/login",
name: "Login",
component: Login,
meta: {
title: "登录"
}
},
// 所有不存在的路由都走404
{
path: "/:pathMatch(.*)*",
name: "NotFound",
component: NotFound,
},
]
// 动态路由,用于匹配菜单,动态添加路由
const dynamicRoutes = [
{
path: "/index",
name: "Index",
component: Index,
meta: {
title: "首页",
}
},
{
path: "/analysis",
name: "Analysis",
component: Index,
meta: {
level: 1, // 是一级路由
title: "可视化大屏",
}
},
]
// 创建路由器,管理所有路由
export const router = createRouter({
history: createWebHashHistory(),
routes
})
// 动态添加路由的方法
export const addRoutes = (menus) => {
// 是否有新的路由
let hasNewRoute = false
// 从动态路由中找菜单
const findRoute = (menuArr) => {
// 遍历每个菜单
menuArr.forEach(menu => {
// 从动态路由中找到和菜单的路径相同的路由
let route = dynamicRoutes.find(route => route.path === menu.url_path)
// 如果找到了,且没有注册过
if (route && !router.hasRoute(route.name)) {
if (route.meta && route.meta.level && route.meta.level === 1) {
// 添加一级路由
router.addRoute(route)
} else {
// 添加子路由
router.addRoute("Layout", route)
}
hasNewRoute = true
}
// 如果还有嵌套路由
if (menu.children && menu.children.length > 0) {
findRoute(menu.children)
}
})
}
// 为菜单动态添加路由
findRoute(menus)
// 返回
return hasNewRoute
}
修改路由拦截器,在用户访问页面之前,根据其菜单动态添加路由:src/router/permission.js
import {addRoutes, router} from "./index.js"
import {getToken} from "../utils/cookie.js";
import {hideFullLoading, showFullLoading, toast} from "../utils/message.js";
import store from "../store/index.js";
// 全局前置守卫
router.beforeEach(async (to, from, next) => {
// 显示loading
showFullLoading()
// 获取token
const token = getToken()
// 还没有登录,且不是访问登录页面,跳转到登录页面
if (!token && to.path !== "/login") {
toast("请先登录", "warning")
return next({path: "/login"})
}
// 防止重复登录:有token,且访问的是登录页面
if (token && to.path === "/login") {
toast("您已经登录过了", "warning")
// 跳转到之前的页面或者首页
return next({path: from.path || "/"})
}
// 判断是否有新的路由
let hasNewRoute = false
// 如果用户登录了,自动化获取用户信息,并存储在vuex中
if (token) {
let userData = await store.dispatch("actionGetUserInfo")
// 动态添加路由
hasNewRoute = addRoutes(userData.menus)
}
// 设置页面标题
document.title = (to.meta.title || "") + "-企业级商城后台管理系统"
// 放行
hasNewRoute ? next(to.fullPath) : next()
})
// 全局后置守卫
router.afterEach((to, from) => hideFullLoading())
另外,在引入了router的地方,需要修改其对router的引入方式:
-
src/main.js
-
src/core/store/index.js
import {router} from "../router/index.js";
标签:菜单,..,import,Vue3,path,router,路由
From: https://www.cnblogs.com/stry/p/17136831.html