vue 权限管理
核心想法: 登陆后获得用户角色,通过角色获得用户的权限,注入权限对应的路由。刷新页面,从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 权限管理的更多相关文章
- vue 权限管理深度探究
实现思路如下:1.网页路由(route)中定义的每个路由都有meta属性,属性值防止可访问该路由的值.2.路由的全局前置守卫(beforeEach)会判断路由用户是否登录(未登录跳转至登录界面),以及 ...
- vue前后分离动态路由和权限管理方案
需求 需要根据不同的角色来显示不同的菜单 问题 系统是前后分离模式开发的,出现了后端接口和前端路由都需要权限管理. 思路 后端的接口肯定得验证权限 在前端做好组件名和组件的映射 前端的路由通过后端发回 ...
- vue基于d2-admin的RBAC权限管理解决方案
前两篇关于vue权限路由文章的填坑,说了一堆理论,是时候操作一波了. vue权限路由实现方式总结 vue权限路由实现方式总结二 选择d2-admin是因为element-ui的相关开源项目里,d2-a ...
- Spring Boot + Vue 前后端分离开发,权限管理的一点思路
在传统的前后端不分的开发中,权限管理主要通过过滤器或者拦截器来进行(权限管理框架本身也是通过过滤器来实现功能),如果用户不具备某一个角色或者某一个权限,则无法访问某一个页面. 但是在前后端分离中,页面 ...
- vue 后台管理系统菜单权限管理
来自:https://www.cnblogs.com/fqh123/p/11094296.html 侵删 login登录方法 login() { if (!this.username) { retur ...
- 权限管理UI
vue+vuex+vue-router+EF的权限管理系统 演示网站 首先说下这个项目吧.如标题一样是基于VUE+.NET开发的框架,也是群友一直吼吼吼要一个vue版本的ABP框架.我们先来看看首页吧 ...
- vue权限路由实现方式总结二
之前已经写过一篇关于vue权限路由实现方式总结的文章,经过一段时间的踩坑和总结,下面说说目前我认为比较"完美"的一种方案:菜单与路由完全由后端提供. 菜单与路由完全由后端返回 这种 ...
- SpringBoot + Apache Shiro权限管理
之前配置过Spring + SpringMVC + JPA + Shiro后台权限管理 + VUE前台登录页面的框架,手动配置各种.xml,比较繁琐,前几天写了个SpringBootShiro的Dem ...
- Vue权限路由实现总结
前言 年前完工了做了半年的铁路后台管理系统,系统整体业务比较复杂,这也是我到公司从 0 到 1 的 一个完整系统实践,做这个系统过程中踩了不少坑,也学到了很多. 做完这个系统没多久,紧接着又一个系统来 ...
随机推荐
- Git reset的参数
(1) 默认的mixed参数:git reset commit_id,将本地版本库的头指针全部重置到指定版本,且会重置暂存区,即这次提交之后的所有变更都移动到未暂存阶段. (2) soft 参数:gi ...
- Git 比较两个分支之间的差异
1.查看 dev 有,而 master 中没有的: git log dev ^master 2.查看 dev 中比 master 中多提交了哪些内容: git log master..dev 注意,列 ...
- VMware Workstation 10 配置Ubuntu环境
分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 VMware Work ...
- Eclipse 连接MySql数据库总结
Eclipse 连接MySql数据库总结 一.在MySql中创建数据库,并创建表,向表中插入数据 1.创建数据库 create database select_test 2.创建表 create ta ...
- 线性回归代码实现(matlab)
1 代价函数实现(cost function) function J = computeCost(X, y, theta) %COMPUTECOST Compute cost for linear r ...
- JavaScript中定义函数的几种方式
函数的组成:函数名 + 函数体 1.使用function关键字定义函数 -- 具有优先级,优先将function关键字定义的函数优先执行 function functionName(arg0, ar ...
- 233 Matrix
233 Matrix 有一\(n\times m\)的矩阵\(\{a\}\),定义\(a[0][0]=0,a[0][1]=233,a[0][2]=2333,a[0][3]=23333...\),然后给 ...
- 从虚拟机视角谈 Java 应用性能优化
从虚拟机视角谈 Java 应用性能优化 周 祥, 软件工程师, IBM 简介:Java 的普及和广泛应用,以及其基于虚拟机运行的机制,使得性能问题越来越重要.本文从 Java 虚拟机的角度,特别是垃圾 ...
- configparser 配置文件模块
#_author:star#date:2019/11/7# configparser 配置文件模块import configparserconfig=configparser.ConfigParser ...
- 【源码】PyObject_VAR_HEAD 定长对象 变长对象
PyObject_VAR_HEAD Python-3.7.4\Include\object.h /* PyObject_VAR_HEAD defines the initial segm ...