vue实现菜单权限管理+刷新后404的解决办法
实现思路vue实现菜单的权限控制主要有两种思路:在路由转发时添加路由拦截,即使用beforeEach拦截没有权限的路由,并跳转到404界面。不过这种实现方法具有一定的缺点,即每次路由切换时都会进行路由拦截的判断。动态添加路由,通过后端返回的菜单,为用户动态添加具有权限的路由。这种只会在系统初始化和页面刷新时调用。一、beforeEach路由拦截为了方便演示,我把后端返回的菜单路由数组存在sessi
·
实现思路
vue实现菜单的权限控制主要有两种思路:
-
在路由转发时添加路由拦截,即使用beforeEach拦截没有权限的路由,并跳转到404界面。不过这种实现方法具有一定的缺点,即每次路由切换时都会进行路由拦截的判断。
-
动态添加路由,通过后端返回的菜单,为用户动态添加具有权限的路由。这种只会在系统初始化和页面刷新时调用。
重点是一定使用router.onReady实现,这种方法比判断store缓存是否存在更好用
一、beforeEach路由拦截
为了方便演示,我把后端返回的菜单路由数组存在sessionStorage中。即代码中的menuList。
// 免登陆白名单
const noLoginWhiteList = ['/login', '/404'];
router.beforeEach((to, from, next) => {
if (noLoginWhiteList.includes(to.path)) { // 如果前进的路由在白名单中则直接跳转
next();
} else if (getSession('userInfo')) { // 如果用户已经登录
const arr = getSession('menuList').map(item => {
return item.url; // 获取所有的有权限的url
});
if (arr.includes(to.path)) {
next(); // 有权限则前进
} else {
next({
path: '/404' //无权限跳转到404
})
}
} else {
next({
path: '/login' //未登录跳转到登录
})
}
})
二、addRoutes+router.onReady 动态添加路由
1、技术介绍
-
addRoutes
动态添加路由,且参数是必须符合路由规则的数组 -
router.onReady
路由初始化时调用,每次当页面刷新时就相当于要初始化一次路由,这时候再调用一遍动态添加路由的方法就能避免跳转到404的错误。
网上很多方法是将菜单信息存储到store中,每次判断store是否存在来判断是否刷新。但是使用onReady不管你如何存储的菜单信息,都可以解决问题。
2、具体步骤
- 定义路由(router下的index.js)
// 菜单项路由
export const menuRoute = [
{
path: '/index1',
component: resolve => require(['@/views/index1/Index1.vue'], resolve)
},
{
path: '/order',
component: resolve => require(['@/views/order/Order.vue'], resolve)
},
{
path: '/bill',
component: resolve => require(['@/views/bill/Bill.vue'], resolve)
},
{
path: '/user',
component: resolve => require(['@/views/user/User.vue'], resolve),
meta: { title: '销售品列收' },
}
];
// 固定已有的路由
export default new Router({
mode: 'history',
routes: [{
path: '/',
redirect: '/user'
},
{
path: '/login',
component: resolve => require(['@/views/login/Login.vue'], resolve),
meta: { title: '登录' },
},
{
path: '/404',
component: resolve => require(['@/components/error-page/404.vue'], resolve)
}]
})
- 新建permission.js
import { getSession } from '@/utils/storage';
import router from './index';
import { menuRoute } from './index';
export function getPermission(){
const menuList = getSession('menuList'); // 获取后端返回的路由
const urls = menuList.map(item => {
return item.url;
})
// 获取有权限的菜单路由(只是我自己项目中根据自己的数据结构的操作,具体看个人项目)
let addGroup = menuRoute.filter(item => {
return urls.includes(item.path);
});
const homeRoute = [
{
path: '/',
redirect: menuList[0].url,
component: resolve => require(['@/views/common/Home.vue'], resolve),
children: addGroup
},
{
path: '*',
redirect: '/404' // 匹配不到的路由一定到放在最后添加,否则页面刷新将跳转到404
}
];
router.addRoutes(homeRoute); // 动态添加
}
- 登录成功后调用动态添加路由的方法
// 伪代码
import { getPermission } from '@/router/permission';
login(() => {
getPermission();
})
- 在main.js添加每次刷新后的处理
// 登录成功时已经添加了一遍,登陆后刷新时才需要再次动态添加
// 页面刷新时重新动态添加路由
if(getSession('userInfo')){ // 是否登录
router.onReady(() => {
getPermission();
})
}
哪里写的不好欢迎指正。
更多推荐
已为社区贡献3条内容
所有评论(0)