前言
在我之前之前的项目中,项目设置的动态路由是通过后端返回的路由权限标识组来进行控制的。
具体代码如下是:
js
// router index.js
// 静态路由表
export const constantRoutes = [
{path: '/login',component: () => import('@/views/login/index'),hidden: true},
{path: '/404',component: () => import('@/views/404'),hidden: true},
{
path: '/',component: Layout,redirect: '/dashboard',
children: [{path: '/dashboard',name: 'Dashboard',
component: () => import('@/views/dashboard/index'),meta: { title: '首页', icon: 'dashboard' }}]
},
]
// 动态路由组
export const MyRouter = [approval,attendance,]
// approval.js
import Layout from '@/layout'
export default {path: '/approval',name: 'approval',component: Layout,
children: [{path: '',name: 'approval',
component: () => import('@/views/approval/index'),
meta: {icon: 'tree-table',title: '审批管理'}}
]}
js
// permission.js
import router from './router'
import store from './store'
import { getToken } from '@/utils/auth'
import { MyRouter} from "./router"
const whiteList = ['/login', '/404']
router.beforeEach(async(to, from, next) => {
// 当然这个地方可以加个进度条,我懒得加
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
next('/')
} else {
// 判断是否有数据
if(!store.getters.userId){
// 获取用户数据
let res = await store.dispatch('user/userInfo')
// 过滤 进行名称匹配
const filterRoutes = MyRouter.filter(item=>{
// 过滤出了来的数据 返回出去、
// 过滤出的权限组 [approval,attendance]
return res.roles.menus.includes(item.name)
})
console.log(filterRoutes);
// 存储在 vuex 中
store.commit('user/setRoutes',filterRoutes)
// 动态添加路由
router.addRoutes([...filterRoutes,{ path: '*', redirect: '/404', hidden: true }])
// router动态添加 目的让路由留有信息
next(to.path)
}
next()
}
} else {
if (whiteList.includes(to.path)) {
next()
} else {
next('/login')
}
}
})
router.afterEach(() => {
})
但是这种添加路由模式有错误:
1.在高版本中addRoutes已经被废除了,无法在继续使用。
2.动态添加时,必须要加上 404页面路由, 不然就会报错。
当然还有其他的路由权限方法。
使用路由权限对象组 (整个路由对象)来设置用户权限。
具体代码如下:
js
// router index.js
Vue.use(VueRouter);
const routes = [
{ name: "login", path: "/login", meta: { title: "登录" }, component: login, hidden: true },
// { name: "404", path: "/404", meta: { title: "404页面" }, component: import("@/views/404.vue"), hidden: true },
];
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes,
});
// permission.js
import router from '@/router';
import store from '@/store';
import layout from '@/views/layout/index.vue';
const filterRoutes = ["/login", "/404"] //需要过滤的数组
router.beforeEach(async (to, from, next) => {
document.title = `${to.meta.title}`; //获取路由中的meta中的title,并设置成页面之间的标题
// 判断路由跳转的页面是否在白名单中
// 在, 直接跳转,不需要判断
if (filterRoutes.indexOf(to.path) !== -1) {
next();
return false
}
if (router.options.routes.length == 1) {
// 获取token 和原始路由数组
const userinfo = await store.dispatch('user/login')
// 当token和原始路由都存在的时候
if (userinfo.token && userinfo.routes) onFilterRoutes(to, next, userinfo.routes) // 执行路由过滤和跳转
else next({ path: "/login", replace: true })
} else next()
})
// 路由拼接
function loadView(view) {
console.log(`@/views/${view}.vue`);
return () => import(`@/views/${view}.vue`)
}
// 路由过滤 及跳转
async function onFilterRoutes(to, next, e) {
const routes = await filterASyncRoutes(e)
routes.sort((a, b) => a['id'] - b['id'])//排序
routes.forEach(item => {
router.options.routes.push(item)
router.addRoute(item)
})
next({ ...to, replace: true })
}
// 路由过滤 遍历路由 转换为组件对象和路径
function filterASyncRoutes(data) {
const routes = data.filter((item) => {
if (item["component"] === "Layout") item.component = layout
else item["component"] = loadView(item["component"])
// 路由递归,转换组件对象和路径
if (item["children"] && item["children"].length > 0) item["children"] = filterASyncRoutes(item.children)
return true
})
console.log(routes);
return routes
}
数据是先用mock进行模拟的
yaml
routes: [
{
id: 1, name: "/", path: "/", component: "Layout", redirect: "/home/index", hidden: false, children: [
{ name: "/home/index", path: "/home/index", meta: { title: "管理首页" }, component: "home/index" }
]
},
{
id: 2, name: "/role", path: "/role", component: "Layout", redirect: "/role/index", meta: { title: "权限管理" }, hidden: false, children: [
{ name: "/index", path: "/role/index", meta: { title: "管理员列表" }, component: "role/index" },
{ name: "/roleuser", path: "/role/roleuser", meta: { title: "角色管理" }, component: "role/roleuser" }
]
},
{
id: 3, name: "/order", path: "/order", component: "Layout", redirect: "/order/index", hidden: false, children: [
{ name: "/order/index", path: "/order/index", meta: { title: "订单管理" }, component: "order/index" }
]
},
{
id: 4, name: "/user", path: "/user", component: "Layout", redirect: "/user/index", hidden: false, children: [
{ name: "/user/index", path: "/user/index", meta: { title: "用户管理" }, component: "user/index" }
]
},
{
id: 5, name: "/commodity", path: "/commodity", component: "Layout", redirect: "/commodity/index", hidden: false, children: [
{ name: "/commodity/index", path: "/commodity/index", meta: { title: " 商品管理" }, component: "commodity/index" }
]
}
]
当然也出现问题。也是最不该的问题
路径名称出现大小写问题。
期初我以为是添加到静态路由表中步进行排查。突然看下文件夹名称,发现我写错了,主要是习惯
大写字母开头。
在之后引以为鉴。