索引
概述
关于动态路由的相关处理,请参考本人的另一篇文章vue.js前后端分离后台,该如何根据用户权限处理前端显示和后台接口访问,本文作为上一篇的续作
有时候仅处理菜单,是不够的,很多情况下,有读的权限,但无写的权限的时候,就需要更灵活的控制。也就是这篇文章的由来。
大概有两种方式可以使用:
- 指令
- 组件
基于指令
关于指令的使用,网上的文章比较多了,主要是操作DOM,把没有权限的元素从已渲染的画面里面删除。这里只是简单的出个示范,具体可以参考自己的授权系统开发:
import Vue from 'vue'
// import Store from '../store/'
const directives = {
role: {
// 指令的定义 (TBD:有没有before'inserted'这样的钩子函数用?)
inserted: (el, binding, vnode) => {
// 权限
if (binding.value && [处理权限的判定]) {
el.parentElement.removeChild(el)
}
}
}
}
Object.keys(directives).forEach(key => {
Vue.directive(key, directives[key])
})
<el-button type="success" icon="el-icon-document" size="small" v-role="xxx-upload"
@click="$router.push({name: 'music-album-multi-upload'})">上传
</el-button>
基于组件
不确定对于vue组件,有没有全局的生命周期钩子,如果有的话,处理起来就更方便了。
下面就以普通的组件形式来说明下处理过程:
写一个全局的组件,注册为v-sec
,其中参数code为访问当前画面segment的授权码。
<template>
<div>
<slot v-if="permitted"></slot>
</div>
</template>
<script>
import vuet from '@/vuet/'
export default {
name: "sec",
props: {
code: {
type: String,
required: true,
default: 'text'
},
},
data() {
return {
permitted: false
}
},
beforeCreate() {
let userSelf = vuet.getModule('user-self')
if (userSelf /* && userSelf.secCodes && userSelf.secCodes.contains(this.code) */) {
this.$nextTick(function () {
this.permitted = true
})
}
}
}
</script>
然后在画面上使用
<v-sec code="xxx-add">
<el-button type="success" icon="el-icon-document" size="small"
@click="$router.push('/sys/module/add')">添加
</el-button>
</v-sec>
与指令的那种方式在使用方面差不多,如果组件的这种方式能避免内嵌的组件被渲染,那效果会比指令的那种好一些。
接下来,在项目只可能就两种方式分别做实验。
权限的定义
画面
一般通过导航+动态路由能控制住的,像画面和菜单。
然后配合路由的全局函数router.beforeEach
基本上比较好实现。
为了配合动态路由,需要指定以下几个字段
- 路径,用于画面跳转,
- 组件名/文件地址,用于路由生成,指向实际的vue文件(我们可以约定-代替路径分隔符:common-main=/src/pages/common/main.vue)
- 画面名,用于显示,导航或Title等地方需要
- icon,有一些样式库里有这个,作为可选项
- show_nav,是否显示在导航中,有一些画面需要参数的话,不能够直接从导航进入,可区分开
页面片段
基本上标记个名字,与画面关联起来以便于管理就可以了。
然后配置后台管理系统,可以通过先通过后台录入画面及画面片段,然后用程序生成对应的vue文件及部分代码。这样子开发效率是不是高一些?
- 画面ID
- 片段编码,不直接使用DB的ID自增,以避免在不同的系统间数据迁移时的问题。
- 片段名,在授权画面展示以方便管理
授权
授权时,把画面和画面片段与角色关联即可,然后用户在登录后获取到角色,再从内存/DB/缓存中把角色对应的画面和菜单等权限查出,合并到一起返回给vue。vue拿到数据后,缓存到localstorage以避免画面的刷新(f5/浏览器刷新)后出现404的问题,这一点在上一篇里面已经说明过了。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。