#### 前言:vue的权限管理,百度过很多,发现他们都是以角色为权限管理,但是要是新增角色就需要修改代码重复设定。
# :-: **准备**
> 使用vue-cli3.0安装vue,并且使用element-ui。具体操作请查看element给vue-cli3.0提供的[插件链接](https://github.com/ElementUI/vue-cli-plugin-element)。
> 项目链接:[https://github.com/chentiewei/all/tree/develop/vue/vueAdminRouter](https://github.com/chentiewei/all/tree/develop/vue/vueAdminRouter)
# :-: **正文**
> 项目文件列表,直接上图
![](https://box.kancloud.cn/2cbc895bb439b163ce9913f59fd43a37_476x930.png)
> 第一步,先做一个登陆页面,并创建账号,每个账号有不同的权限。
> 新建login.vue页面,为登陆页面,很一般就是一个普通的登陆页面
```
<template>
<div class="login_box">
<el-form label-position="right" label-width="60px" :model="loginfrom">
<el-form-item label="用户名">
<el-input v-model="loginfrom.username"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input type="password" v-model="loginfrom.password"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submituUserInfo(loginfrom)">登录</el-button>
</el-form-item>
</el-form>
<div class="msg">
<span>账号:admin</span>
<span>账号:a</span>
<span>账号:b</span>
<span>账号:c</span>
</div>
</div>
</template>
<script>
export default {
name: 'login',
data () {
return {
loginfrom:{
username:'',
password:'123456'
}
}
},
methods:{
submituUserInfo(data){//登陆提交方法
this.$store.dispatch('Logins',data).then(res => {//vuex登陆方法
this.$router.push({ path: '/' });//登陆成功默认跳转页面
}).catch(() => {
})
}
}
}
</script>
```
> login.js里面包含了用户的登陆信息,一般是由ajax完成的,但是我们这边简化他所以使用固定的登陆信息。
> 里面的role数组就是他的权限了
```
/*暴露接口为loginByUserInfo*/
export const loginByUserInfo = [
{"id": 1, "username": "admin", "pew": 123456, "role": [{ "name":"home"},{ "name":"red"}, {"name": "yellow"}, {"name": "blue"},{ "name":"all"}] , "introduce":"我可以看见全部页面"},
{"id": 2, "username": "a", "pew": 123456, "role": [{ "name":"home"},{"name": "blue"},{ "name":"all"}] , "introduce":"我可以看到home,blue和all页面"},
{"id": 3, "username": "b", "pew": 123456, "role": [{ "name":"home"},{ "name":"red"}], "introduce":"我可以看见red和home页面"},
{"id": 3, "username": "c", "pew": 123456, "role": [{ "name":"home"},{ "name":"red"},{ "name":"all"}], "introduce":"我可以看见home,red和all页面"},
]
```
> router.js要注意,里面有2个模块一个为公共router,一个为私有router,而私有router是经过,和后台交互获取权限我们这里用了login.js来模拟。
```
import Vue from 'vue'
import Router from 'vue-router'
/*页面声明*/
import home from '@/views/home'
import login from '@/views/login'
import red from '@/views/red'
import yellow from '@/views/yellow'
import blue from '@/views/blue'
import all from '@/views/all'
import all1 from '@/views/all1'
import all2 from '@/views/all2'
Vue.use(Router)
/*公有router*/
export default new Router({
routes: [
{
path: '/login',
name: 'login',
component: login
}
]
})
/*私有router*/
export const powerRouter = [
{path: '/', name: 'home', component: home},
{path: '/red', name: 'red', component: red},
{path: '/yellow', name: 'yellow', component: yellow},
{path: '/blue', name: 'blue', component: blue},
{
path: '/all', name: 'all', component: all,
children: [
{path: '/all1', name: 'all1', component: all1,},
{path: '/all2', name: 'all2', component: all2,}
]
}
];
```
> store里面包含登陆,登出,权限方法,已经变量用户,权限和新权限列表。
```
import Vue from 'vue'
import Vuex from 'vuex'
import { loginByUserInfo }from '@/api/login'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
username: sessionStorage.getItem('USERNAME'),
role: JSON.parse(sessionStorage.getItem('ROLE')),
newrouter: [],
},
getters: {
username: state => state.username,
role: state => state.role,
newrouter: state => state.newrouter
},
mutations: {
SET_USERNAME:(state, username) => {
state.username = username;
},
SET_ROLE:(state, role) => {
state.role = role;
},
SET_NEWROUER:(state, newrouter) =>{
state.newrouter = newrouter;
},
},
actions: {
Logins({ commit }, info){/*登陆方法*/
return new Promise((resolve, reject) => {
let data={};
loginByUserInfo.map(function (item) { //获取所以用户信息
if(info.username === item.username || info.pew === item.pew){
commit('SET_USERNAME',item.username); //将username和role进行存储
sessionStorage.setItem('USERNAME', item.username); //存入 session
commit('SET_ROLE',item.role);
sessionStorage.setItem('ROLE',JSON.stringify(item.role)); //存入 session
return data={username:item.username,introduce:item.introduce};
}else{
return data;
}
});
resolve(data);
}).catch(error => {
reject(error);
});
},
Roles({ commit }, newrouter){
return new Promise((resolve, reject) => {
commit('SET_NEWROUER',newrouter); //存储最新路由
resolve(newrouter);
}).catch(error => {
reject(error);
});
},
Logout({ commit, state }) {/*登出方法*/
return new Promise((resolve, reject) => {
commit('SET_USERNAME','');
commit('SET_ROLE','');
commit('SET_NEWROUER',[]);
sessionStorage.removeItem('USERNAME');
sessionStorage.removeItem('ROLE');
resolve();
}).catch(error => {
reject(error);
});
}
}
})
```
> main.js使用router.beforeEach来监控每个页面是不是达到要求
> 先引入router.js的powerRouter私有router。并且引入vuex
```
import { powerRouter } from './router';
import store from './store'
```
```
router.beforeEach((to, from, next) => {
let _role=store.getters.role
if(_role){ //判断role 是否存在
if(store.getters.newrouter.length !== 0){//判断vuex的newrouter是否为空
next();
}else{
let newrouter=[];
_role.forEach((i)=>{
powerRouter.forEach((k)=>{
if(k.name==i.name){//判断用户登陆信息role有哪些,用name比对。
newrouter.push(k)
}
})
})
router.addRoutes(newrouter) //添加动态路由
store.dispatch('Roles',newrouter).then(res => {//使vuex的newrouter保留私有rouer列表
next({ ...to })
}).catch(() => {
})
}
}else{
if (['/login'].indexOf(to.path) !== -1) {
next()
} else {
next('/login')
}
}
})
```
> 最后以home.vue结尾,这里我特别注意,为什么使用vuex的newrouter列表进行循环而不是用router列表直接循环呢?因为我们使用的是addRouters,此方法如何直接使用router列表循环不会更新,所以我们使用vuex的newrouter。
```
<template>
<div>
<div class="header">
<div v-for="(v,i) in newrouter" :key="i"><!--vuex的newrouter-->
<router-link :to="{name:v.name}" v-if="!v.children">{{v.name}}</router-link>
<div v-else-if="v.children">{{v.name}}</div><!--判断是不是有子router-->
<div v-for="(k,j) in v.children"><!--判断是不是有子router-->
<router-link :to="{name:k.name}">{{k.name}}</router-link>
</div>
</div>
</div>
<div class="main">
<router-view></router-view>
</div>
<el-col :span="1" class="out">
<div class="logout_box" @click="logout()">退出</div>
</el-col>
</div>
</template>
<script>
import { mapGetters } from 'vuex';
export default {
name: 'home',
data () {
return {
newrouter:this.$store.state.newrouter//vuex的newrouter第一种展现形式
}
},
created(){
},
computed: {
/*...mapGetters([//vuex的newrouter第二种展现形式
'newrouter'
])*/
},
methods: {
logout(){//为登出按钮
this.$store.dispatch('Logout').then(() => {
this.$router.push({ path: '/login' });
}).catch(err => {
this.$message.error(err);
});
}
},
mounted(){
}
}
</script>
```
# :-: **功能加强**
> 上面代码有缺陷,仔细查看的会发现他不能控制子路由。也不能控制一些添加删除页面。
> 我们需要修改router.js和main.js
> 项目链接:[https://github.com/chentiewei/all/tree/develop/vue/vueAdminRouter2](https://github.com/chentiewei/all/tree/develop/vue/vueAdminRouter2)
> router.js的powerRouter修改为**powerRouterLazy**
```
export function powerRouterLazy(name) {
switch (name) {
case 'home':
return {path: '/', name: 'home', component: home}
break;
case 'red':
return {path: '/red', name: 'red', component: red}
break;
case 'yellow':
return {path: '/yellow', name: 'yellow', component: yellow}
break;
case 'blue':
return {path: '/blue', name: 'blue', component: blue}
break;
case 'all':
return {path: '/all', name: 'all', component: all,children: []}
break;
case 'all1':
return {path: '/all1', name: 'all1', component: all1}
break;
case 'all2':
return {path: '/all2', name: 'all2', component: all2}
break;
}
}
```
> main.js方法
```
let generaMenu = (obj,data) =>{ /*循环router方法*/
data.forEach((v,i)=>{
obj.push(powerRouterLazy(v.name))
if(v.children){
generaMenu(obj[i].children,v.children)//递归children
}
})
}
router.beforeEach((to, from, next) => {
let _role=store.getters.role
if(_role){ //判断role 是否存在
if(store.getters.newrouter.length !== 0){//判断newrouter是否为空
next()
}else{
let newrouter=[]
generaMenu(newrouter,_role)/*router循环*/
router.addRoutes(newrouter) //添加动态路由
store.dispatch('Roles',newrouter).then(res => {
next({...to})
}).catch(() => {
})
}
}else{
if (['/login'].indexOf(to.path) !== -1) {/*是否为login*/
next()
} else {
next('/login')
}
}
})
```
> 上述代码可以控制,新增,编辑,添加,和子路由。这样就是一个完整的权限管理了
#
#
ヘ(;´Д`ヘ)
(/゚Д゚)/
(\*゜ロ゜)ノ
Σ(  ̄д ̄;)
#### 小结:上述代码想法是,**用户登陆--获取用户权限--跳转使用beforeEach判断权限--判断完成提交vuex--最后页面根据vuex变量循环**,这边其实还有一个思路,在router注册前就把 权限router给整理出来,然后在注册,这样更加的简单,清晰。
- vue
- axios封装全局loading(1)
- axios封装全局loading(2)
- axios封装全局loading(3)
- 学不动也要学,vue权限管理
- 判断前台当前页面是否需要token
- vue打包为APP(1)
- vue-cli3.0跨域
- vue-cli 3.0配置目录别名alias
- px自动转换rem
- 页面返回位置保留
- 浏览器title动态修改
- vue路由参数变化页面不刷新
- react
- 学不动也要学,react(1)
- Electron
- Electron厉害的要死(1)
- Electron厉害的要死(2)
- node
- 前后端分离
- MVC项目
- HTML
- 缓存时间机制
- 全站执行https请求
- 移动端meta
- CSS
- sticky_footer
- JS
- 子元素是否超出父元素
- iframe切换
- 获取url参数
- 回到顶部按钮
- 滚动条是否到达底部
- 移动端左右滑动div
- 移动pc相互跳转
- IE浏览器版本判断
- 调用摄像头和相册
- 抽奖概率
- cookie
- 平常小知识
- 单行文本与多行文本省略号
- display:table用法
- span标签document绑定事件失效
- 添加script标签
- 内联元素不能紧贴
- 3D旋转(transform)粗细渲染
- 全英文不换行问题
- 点击input出现蓝色边框
- wap端点击div,a,img出现阴影效果
- 华为手机使用flex布局,样式位移
- IE兼容性
- 图解
- 其他
- 未整理