17-----vue前端权限管理
原理:
1.后台同学返回一个json格式的路由表,再这个实例中,我们使用的是文件动态路由的形式;
2.动态路由,每个路由根据自己的权限字段,设定好权限字段。
3.利用vue-router的beforeEach、addRoutes、localStorage来配合上边两步实现效果;
4.左侧菜单栏根据拿到转换好的路由列表进行展示;
大体步骤:拦截路由->后台取到路由->保存路由到localStorage(用户登录进来只会从后台取一次,其余都从本地取,所以用户,只有退出在登录路由才会更新)
1、首先定义我们的路由文件:
import Login from './views/Login.vue' import NotFound from './views/404.vue' import Home from './views/Home.vue' import Main from './views/Main.vue' import Table from './views/nav1/Table.vue' import Form from './views/nav1/Form.vue' import user from './views/nav1/user.vue' import Page4 from './views/nav2/Page4.vue' import Page5 from './views/nav2/Page5.vue' import Page6 from './views/nav3/Page6.vue' import echarts from './views/charts/echarts.vue' import UserManager from './views/users/UserManager' import Permission from './views/users/Permission' import Role from './views/users/Role' let routes = [ { path: '/login', component: Login, name: '', hidden: true }, { path: '/404', component: NotFound, name: '', hidden: true }, //{ path: '/main', component: Main }, ]; export default routes; export const powerRouter = [ { path: '/', component: Home, name: '系统管理', iconCls: 'fa el-icon-message',//图标样式class role:['role'], children: [ { path: '/main', component: Main, name: '主页', hidden: true }, // 子菜单列表 // { path: '/table', component: Table, name: 'Table' }, //{ path: '/form', component: Form, name: 'Form' }, // { path: '/permission', component: Permission, name: '权限管理' }, { path: '/role', component: Role, name: '角色管理' }, { path: '/user', component: UserManager, name: '用户管理' }, ] }, { path: '/', component: Home, name: '导航二', iconCls: 'fa fa-id-card-o', role:['role'], children: [ { path: '/page4', component: Page4, name: '页面4' }, { path: '/page5', component: Page5, name: '页面5' } ] }, { path: '/', component: Home, name: '', iconCls: 'fa fa-address-card', leaf: true,//只有一个节点 // role:['cmdb','role','user'], children: [ { path: '/page6', component: Page6, name: '导航三' } ] }, { path: '/', component: Home, name: 'Charts', iconCls: 'fa fa-bar-chart', // role:['cmdb','role','user'], children: [ { path: '/echarts', component: echarts, name: 'echarts' } ] }, { path: '*', hidden: true, // role:['role','user'], redirect: { path: '/404' } } ];
2、路由拦截: main.js
import routes from './routes' import { powerRouter } from './routes.js'; // 路由卫士,判断路由权限 router.beforeEach((to, from, next) => { if (store.state.user) { //判断role 是否存在 // console.log('dddddddddd', store.state.user); if (store.state.newrouter.length !== 0) { next(); } else { let newrouter = []; let _role = store.state.user.roles; // ##从后端获取权限,默认权限是['admin','user']这种数组形式 _role.forEach((i) => { console.log("_role:::::::::::::::::::",_role); console.log('i::::::', i);// ##遍历里面的权限 powerRouter.forEach((k) => { console.log("powerRouter::::::::::::",powerRouter); console.log("k:::::::::::::::::",k) // ##遍历定义的路由信息 if (k.role==null){ return true; } k.role.forEach((j) => { console.log("k.role:::::::::::::::::",k.role); console.log("j:::::::::::::::::",j) if (j === i) { // ##相关参数做比对,符合权限的,添加到路由 newrouter.push(k); console.log('kkkkkkk', k); console.log('jjjjjjj', j); console.log('iiiiii', i); } } ) }); }); //404的页面再最后加,不然总数访问到的都是404界面 newrouter.push({ path: '*', redirect: '/404' }); console.log('11111111', _role) router.addRoutes(newrouter); //添加动态路由 store.dispatch('NewRouter', newrouter).then(res => { next({...to}) }).catch(() => { }) } } else { if (['/login'].indexOf(to.path) !== -1) { next() } else { next('/login') } } });
3、vuex路由管理。
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); // 创建基本状态 const state = { user: JSON.parse(localStorage.getItem('user')) || '', newrouter: [] }; // 创建改变状态的方法 const mutations = { // 登录 LOGIN(state) { state.user = JSON.parse(localStorage.getItem('user')) newrouter: [] }, // 登出 LOGOUT(state) { state.user = '' localStorage.removeItem('token') localStorage.removeItem('user') newrouter: [] }, NewRouter(state, newrouter) { state.newrouter = newrouter }, CleanRouter(state) { state.newrouter = [] } } // 创建驱动actions可以使得mutations得以启动 const actions = { // 这里先来一个驱动LOGIN的东西就叫login吧 login({commit}) { commit('LOGIN') }, // 同样来个logout logout({commit}) { commit('LOGOUT') }, NewRouter({commit}, newrouter) { commit('NewRouter', newrouter) }, CleanRouter({commit}) { // 登陆之前清控路由表 commit('CleanRouter') } } export default new Vuex.Store({ state, mutations, actions })
4、前端根据过滤出的路由生成侧边栏,替换到路由:
computed: { routes() { return this.$store.state.newrouter } },
5、剩下的就是侧边栏路由遍历信息:
<template v-for="(item,index) in routes" v-if="!item.hidden">
6、这样就形成了,不同的用户登录具有不同的展示和权限。
本文来自博客园,作者:王竹笙,转载请注明原文链接:https://www.cnblogs.com/edeny/p/12686890.html