1.假设admin是超级管理员,那么得到的就是所有的路由,界面显示(概况,组件,权限)
2.normal是普通管理员,只能看见部分,界面显示(概况,组件)
大概的逻辑就是这样,在获取权限之前,肯定要先登录,不然怎么知道你是谁呢?你能干嘛呢?
登录
只追求功能实现的,可以先随便弄两个输入框加上一个确定按钮,给确定按钮绑定click事件。有强迫症的我,还是给美化了下,然后在提交之前进行表单验证,效果如下:(账号是随机生成的)
验证完成,实现登录之后,我们进行用户信息保存操作。
获取用户信息
this.$http.post('/login', _data).then((response) => { // 保存用户信息(StoreUser/setUser) this.$store.dispatch('StoreUser/setUser', response.data).then(() => { }); });
登录成功后,服务端会返回客户的信息,用了VUEX这个状态管理工具,优先保存在一个用户的状态信息,因为有可能在多处会用到这个信息,例如个人中心等等页面。
const state={ 'isLogin':false }; const mutations = { 'SET_USER':function(state,userData){ state = _.assign(state,userData); Cookie.set('accountData', state); }, 'REMOVE_USER':function(state){ state = _.assign(state,{ 'isLogin':false }); Cookie.remove('accountData'); } }; const actions = { 'setUser':function({commit},userData){ commit('SET_USER',userData); }, 'removeUser':function({commit}){ commit('REMOVE_USER'); } };
再将这个用户信息保存Cookie中,用做会话处理,这样下次打开页面或者刷新页面的时候能记住用户的登录状态。这里使用了js-cookie这个工具。
生成权限路由表
获取用户信息,就能知道这个用户的权限范围了,然后我们根据这个权限生成对应的路由表
this.$store.dispatch('StoreAddRoutes/getRoutes',_roles).then(() => { // 根据_roles权限生成可访问的路由表 // 动态添加可访问路由表 this.$router.addRoutes(this.$store.getters.addRoutes); // 黑科技 window.location.replace('/'); });
StoreAddRoutes/getRoutes这个方法是如何呢?
const state = { 'addRoutes': [] }; const actions = { 'getRoutes':function({commit},roles){ if (_.indexOf(roles, 'admin') !== -1) { commit('SET_ROUTERS',adminRoutes()); } else { commit('SET_ROUTERS',normalRoues()); } } };
通过StoreAddRoutes/getRoutes返回的路由信息this.$store.getters.addRoutes,主要是用了vue2.2.0以后新增了router.addRoutes的方法进行动态添加,注意addRoutes()这个方法添加是数组!
重点是这句:this.$router.addRoutes(this.$store.getters.addRoutes);
在actions中,我们根据权限分了adminRoutes和normalRoutes这两个路由表,分别对应超级管理员和普通管路员
整体路由表
从上面获取可以看出由权限分出的两个路由表,那么这两个adminRoutes和normalRoutes是怎么来的呢?
/** * [AdminRouter 超级管理员] * @type {Array} */ export function adminRoutes() { layoutObj.children = layoutObj.children.concat([ RoleRouter ]); return [commonRoutes(),layoutObj]; } /** * [NormalRouer 普通用户] * @type {Array} */ export function normalRoues() { return [commonRoutes(),layoutObj]; }
其中commonRoutes()是公共页面,例如登录,404等页面
/** * 公共路由 * @type {Array} */ export function commonRoutes() { return LoginRouter; }
而layoutObj这个就是整个布局信息,包括:侧边栏SideBar,右边帮助Help,底部Footer和中间内容Comtainer
import LoginRouter from '@/pages/login/router.js'; import HomeRouter from '@/pages/home/router.js'; import RoleRouter from '@/pages/role/router.js'; import ModuleRouter from '@/pages/module/router.js'; const Comtainer = resolve => require(['@/components/layout/layout'],resolve); const SideBar = resolve => require(['@/components/layout/sidebar'],resolve); const Help = resolve => require(['@/components/layout/help'],resolve); const Footer = resolve => require(['@/components/layout/footer'],resolve); let layoutObj = { 'path': '/', 'name': 'layout', 'components': { 'default' : Comtainer, 'sidebar' : SideBar, 'help' : Help, 'appFooter': Footer }, 'redirect': '/index', 'children': [ HomeRouter, ModuleRouter ] };
看完整个路由表的信息,这样就能很容易通过不同的权限,放置不同的页面路由,从而进行权限控制。
注意到上边我提到的黑科技没?
在动态添加完路由表之后,进行页面首页跳转。而不是使用this.$router.push()这个方法跳转?因为如果使用这个方法,会一直警告有重复路由的警告,看了源码大概是因为addRoutes()这个方法,框架并没有提供删除路由的方法,添加了就一直会存在浏览器中,因此用黑科技,将页面刷新。
// 黑科技 window.location.replace('/');
路由拦截
router.beforeEach((to, from, next) => { if (Cookie.getJSON('accountData') && Cookie.getJSON('accountData').isLogin) { // 判断是否有cookie next();//当有用户权限的时候,说明所有可访问路由已生成 如访问没权限的全面会自动进入登录页面 } else if (to.path === '/login') { next(); } else { next('/login'); //当有用户权限的时候,说明所有可访问路由已生成 如访问没权限的全面会自动进入404页面 } });
拦截器是为了防止用户直接输入地址进行跳转,因为你都没登录,怎么可能就让你进行访问呢!!
当cookie存在用户信息的时候,说明是登录状态,可以进行正常访问,如果不是登录状态,那么只能跳转到登录状态。
预览地址:
http://www.developcls.com/qa/6cf2cc134d364579b76329223f7bf51d.html
http://www.developcls.com/qa/3eaea6f7e1c04a489072879d93c590f9.html