核心想法:

登陆后获得用户角色,通过角色获得用户的权限,注入权限对应的路由。刷新页面,从localStorage用角色(更好的方式是通过token)再次获得所属权限,再次注入路由。在管理界面左端循环权限对应的路由菜单
localStorage存用户的信息(token),权限路由不会存。
所有的路由分为2种:
  • 公共路由:所有用户可以查看。
  • 权限路由:当前用户权限所属的路由。
实现控制的方式分两种:
  • 通过 vue-router addRoutes 方法注入路由实现控制
  • 通过 vue-router beforeEach 钩子限制路由跳转
一般来讲,需要采用第一种方式,addRoutes注入的方式,第二种每次判断,开销比较大,而且一次性拿不到角色对应的所有路由列表。这个列表需要再登陆后立即渲染在左边。


权限的控制分为好几种:
  • 一级菜单的权限控制,
  • 二级菜单的权限控制,
  • 按钮级别的权限控制。
控制方式有2种:
  • 后端返回路由控制列表
  • 前后端约定路由控制列表
代码:一级菜单的权限控制,前后端约定的方式确定角色能访问的路由。
routers/index.js

 

import Vue from 'vue'
import Router from 'vue-router'
import loginRoute from './modules/login.js';
import homeRoute from './modules/home.js'
import productionRoute from './modules/production.js';
import store from '../stores/index.js'; Vue.use(Router) //不需要权限的路由
export const constantRoutes = [loginRoute];
//需要权限的路由
//这里只是导出。实际上添加到router里在在store的permission里
export const asyncRoutes = [
homeRoute,
productionRoute,
];
console.log(asyncRoutes);
const router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
...constantRoutes,
]
})
router.beforeEach((to,from,next)=>{
let user = store.state.user.user;
let permissionRoutes= store.state.permission.permissionRoutes;
console.log(store.state);
console.log(user);
if(!user && to.path!=='/'){
next({
path:'/'
});
}else{
//刷新页面的情况
if(!permissionRoutes && user){
store.dispatch('generateRoutes',{
role:user.role
}) console.log(router);
console.log(to);
//这里写next没用
next({...to})
}else{
next();
} // next({...to, replace: true })
}
});
export default router;

  其中,productionRoute:

import Layout from '../../layouts/Index.vue'
const productionAdd = () => import('../../pages/production/Add.vue')
const productionList = () => import('../../pages/production/List.vue')
const productionTemplateComplete = () => import('../../pages/production/TemplateComplete.vue')
let routes = {
path: '/production',
component: Layout,
meta: {
title: '产品管理',
roles: [0, 1]
},
children: [
{
path: 'add',
component: productionAdd,
beforeEnter (to, from, next) {
console.log('router beforeEnter');
next();
},
meta: {
title: '产品新增'
}
},
{
path: 'list',
component: productionList,
meta: {
title: '产品列表'
}
},
{
path: 'templateComplete',
component: productionTemplateComplete,
meta: {
title: '产品新增完善'
}
}
]
} export default routes

  

stores/index.js
import Vue from 'vue'
import Vuex from 'vuex' import user from './modules/user.js'
import permission from './modules/permission.js' Vue.use(Vuex) export default new Vuex.Store({
modules: {
user,
permission,
}
})

  


stores/modules/user.js
const SET_USER = 'SET_USER' //登录成功
const CLEAR_USER = 'CLEAR_USER' //退出登录
import $ajax from '../../axios/index.js';
import store from '../index.js';
export default {
state: {
user:JSON.parse(localStorage.getItem('user')) || null
},
mutations: {
[SET_USER](state, user) {
state.user = user;
localStorage.setItem('user', JSON.stringify(user))
}, [CLEAR_USER](state) {
state.user = null;
localStorage.removeItem('user');
}
},
actions: {
login({commit}, param) {
console.log('action');
console.log(param);
return new Promise((resolve, reject) => {
//一期不做后台登陆,前端判断
// $ajax({
// url:api.login,
// data:{
// ...param
// }
// }).then(res=>{
// let user = res.data.data;
// commit(SET_USER, user);
// resolve();
// }).catch(res=>{
// reject();
// })
//前端验证用户名,密码
window.setTimeout(()=>{
if(param.username === 'huainanju' && param.password === 'huainanju123'){
let user = {
username:'管理员',
role:0
}
commit(SET_USER, user);
store.dispatch('generateRoutes',{
role:user.role
})
resolve();
}else{
reject();
}
},1000)
});
},
logout({commit}) {
commit(CLEAR_USER)
}
}
}

  


stores/modules/permisson.js
import {asyncRoutes} from '../../routers/index';
import router from '../../routers/index';
/**
* 递归过滤异步路由表,返回符合用户角色权限的路由表
* @param role
*/
function filterAsyncRoutes(role) {
const res = asyncRoutes.filter(route => {
return route.meta.roles.includes(role)
});
return res
} const permisssion = {
state:{
permissionRoutes:null
},
getter:{ },
mutations:{
SET_ROUTERS: (state, routes) => {
//添加路由
console.log('添加路由');
router.addRoutes(routes);
state.permissionRoutes = routes // 权限路由
},
},
actions:{
generateRoutes({ commit }, data) {
let {role} = data;
let routes = filterAsyncRoutes(role);
console.log(routes);
commit('SET_ROUTERS', routes)
}
}
} export default permisssion;

  

layouts/Left.vue
<template>
<el-aside style="min-height:100%;min-width:250px;" width="250px">
<el-menu :default-active="defaultActive"
background-color="#324157"
text-color="#bfcbd9"
active-text-color="#409EFF"
style="position:fixed;top:0;left:0;min-height: 100%;width:250px;z-index:100"
router>
<template v-for="(item,index) in permissionRoutes">
<!--一级菜单-->
<el-menu-item :index="item.path" v-if="item.children.length === 1 ">
<i class="el-icon-menu"></i>
<!-- <div>我是</div>-->
<span>{{item.meta.title}}</span>
</el-menu-item>
<!--多级菜单-->
<el-submenu :index="index+''" v-else>
<template slot="title">
<i class="el-icon-menu"></i>
<span>{{item.meta.title}}</span>
</template>
<template v-for="child in item.children">
<el-menu-item :index="item.path+'/'+child.path">{{child.meta.title}}</el-menu-item>
</template>
</el-submenu>
</template>
</el-menu>
</el-aside>
</template>
<script>
import {mapState} from 'vuex' export default {
data() {
return {
}
},
computed: {
...mapState({
'permissionRoutes':state=>state.permission.permissionRoutes
}),
defaultActive: function () {
if (this.$route.path.indexOf('/classInfo') >= 0) {
return 'classList'
}
return this.$route.path.replace('/org/', '');
}
},
created() {
window.setTimeout(()=>{
console.log(this.permissionRoutes);
},1000)
}
}
</script>

  


vue 权限管理的更多相关文章

  1. vue 权限管理深度探究

    实现思路如下:1.网页路由(route)中定义的每个路由都有meta属性,属性值防止可访问该路由的值.2.路由的全局前置守卫(beforeEach)会判断路由用户是否登录(未登录跳转至登录界面),以及 ...

  2. vue前后分离动态路由和权限管理方案

    需求 需要根据不同的角色来显示不同的菜单 问题 系统是前后分离模式开发的,出现了后端接口和前端路由都需要权限管理. 思路 后端的接口肯定得验证权限 在前端做好组件名和组件的映射 前端的路由通过后端发回 ...

  3. vue基于d2-admin的RBAC权限管理解决方案

    前两篇关于vue权限路由文章的填坑,说了一堆理论,是时候操作一波了. vue权限路由实现方式总结 vue权限路由实现方式总结二 选择d2-admin是因为element-ui的相关开源项目里,d2-a ...

  4. Spring Boot + Vue 前后端分离开发,权限管理的一点思路

    在传统的前后端不分的开发中,权限管理主要通过过滤器或者拦截器来进行(权限管理框架本身也是通过过滤器来实现功能),如果用户不具备某一个角色或者某一个权限,则无法访问某一个页面. 但是在前后端分离中,页面 ...

  5. vue 后台管理系统菜单权限管理

    来自:https://www.cnblogs.com/fqh123/p/11094296.html 侵删 login登录方法 login() { if (!this.username) { retur ...

  6. 权限管理UI

    vue+vuex+vue-router+EF的权限管理系统 演示网站 首先说下这个项目吧.如标题一样是基于VUE+.NET开发的框架,也是群友一直吼吼吼要一个vue版本的ABP框架.我们先来看看首页吧 ...

  7. vue权限路由实现方式总结二

    之前已经写过一篇关于vue权限路由实现方式总结的文章,经过一段时间的踩坑和总结,下面说说目前我认为比较"完美"的一种方案:菜单与路由完全由后端提供. 菜单与路由完全由后端返回 这种 ...

  8. SpringBoot + Apache Shiro权限管理

    之前配置过Spring + SpringMVC + JPA + Shiro后台权限管理 + VUE前台登录页面的框架,手动配置各种.xml,比较繁琐,前几天写了个SpringBootShiro的Dem ...

  9. Vue权限路由实现总结

    前言 年前完工了做了半年的铁路后台管理系统,系统整体业务比较复杂,这也是我到公司从 0 到 1 的 一个完整系统实践,做这个系统过程中踩了不少坑,也学到了很多. 做完这个系统没多久,紧接着又一个系统来 ...

随机推荐

  1. 19.SimLogin_case08

    # 模拟登录微博 import time import base64 import rsa import binascii import requests import re import rando ...

  2. 9.2 sun.py

    import requests from bs4 import BeautifulSoup url = 'http://wz.sun0769.com/index.php/question/reply? ...

  3. POJ 2318 /// 判断点与直线的位置关系

    题目大意: n块玩具箱隔板 m个玩具落地点 给定玩具箱的左上和右下两个端点 接下来给定n块隔板的上点的x和下点的x(因为y就是玩具箱的上下边缘) 接下来给定m个玩具落地点 输出n+1个区域各有的玩具数 ...

  4. Spring 事务传播行为(12)

    事务传播行为 指定是Spring中一个事务方法调用另一个事务方法时.处理的行为 使用方式: @Transactional(propagation=Propagation.REQUIRED) 事务的使用 ...

  5. CentOS7-Minimal安装MySQL服务

    CentOS7默认安装的是Mariadb而不是mysql,而Mariadb是mysql的一个分支, 安装mysql会覆盖Mariadb 一.下载MySQL官方的 Yum Repository [roo ...

  6. sqlite获取表字段

    sqlite下能通过sqlite_master获取指定数据库的表信息和表结构 但是通过sqlite_master不能获取表字段的信息 如果需要获取指定表字段的所有信息 可以使用如下语法: PRAGMA ...

  7. 【自家测试】2017-12-16 FJOI2016 d1

    1. 所有公共子序列问题(allcs.pas/c/cpp)★问题描述:一个给定序列的子序列是在该序列中删去若干元素后得到的序列.确切地说,若给定序列X= x 1 x 2 ... x m ,则另一序列Z ...

  8. SSM项目实现连接两个mysql数据库

    最近做项目需要用到另一个数据库的内容,多方查找终于实现了功能. 我们都知道,在SSM框架中,我们在applicationContext.xml配置文件中添加数据源就可以实现数据库增删改查,但是只能连接 ...

  9. js 面向对象几种数据模式

    一.单例模式: 把描述同一事物的属性和方法放在同一内存空间下,实现了分组的作用,防止同一属性或者方法冲突.我们把这种分组编写代码的模式叫做单例模式即普通的对象. 单例模式是项目开发中最常用的一种开发模 ...

  10. 服务器迁移部署OmsWeb

    绑定 基本设置 高级设置