v-roler

a vue plugin about fine-grained access control

Usage no npm install needed!

<script type="module">
  import vRoler from 'https://cdn.skypack.dev/v-roler';
</script>

README

介绍

IMAGE IMAGE

使用简单的vue指令,即可完成元素级别的权限控制功能(只支持vue3.x以上版本,未对vue2.x做兼容)

使用方法

一、通过yarn或npm安装v-roler

npm install v-roler

二、安装插件

在你的vue实例中,安装插件

import {createApp} from "vue";
import vRoler from "v-roler";
import App from './App.vue';

createApp(App)
.use(vRoler({
    //权限路由,如果没有声明在roles数组里,那么在组件中使用权限指令的元素将被移除
    roles:["view","add","delete"],
    //希望使用的自定义指令,如command:"test",那么在组件中就需要使用v-test作为指令控制权限
    command:"can"}))
.mount('#app');

如上所示,下面所有的使用示例都默认初始化时只声明了"view","add","delete"三个权限。

三、使用

1、使用指令控制权限(推荐)

比如在某个组件中需要对某个组件中的元素进行权限控制渲染,如在a.vue中:

<Parent>
    <ChildA v-can:view>
        <span>查看权限</span>
    </ChildA>
    <ChildB v-can:create>
        <span>添加权限</span>
    </ChildB>
</Parent>

显示的结果是,ChildA被渲染,ChildB被删除,原因是在初始化插件vRoler时,ChildA指令传入的"view"权限已经被声明在权限数组中,所以会正常渲染,但是ChildB的指令传入的"create"并不在初始化的权限数组中.

提示:指令中支持v-xx:view或者:v-xx="'view'"的方式。

2、使用roler-view组件

v-roler在全局注册了roler-view组件,你可以将任何需要做权限控制的元素或内容用roler-view来包裹着,roler-view本身只接收一个熟悉role,其作用和指令一致。

<roler-view role="view">
    查看权限
        <roler-view role="edit">编辑权限</roler-view>
        <roler-view role="delete">删除权限</roler-view>
</roler-view>

视图只会渲染查看权限和删除权限,因为在插件初始化时并没有声明edit的权限路由。

3、使用hook更改权限

v-roler允许用户在setup中通过useRoler这个hook来更改权限数组(也就是插件初始化时传入的roles选项),这是每个组件渲染前最后一次更改权限的机会。同时useRoler返回的权限列表是个reactive对象,能够精细地触发对应的roler-view组件更新自身显示状态(这也是使用组件和指令的区别)。

import {useRoler} from "v-roler";

export default {
    name:"componentA",
    props:{},
    ...,
    setup(){
        const [roles,resetRoles] = useRoler();
        roles.push("xxx");
        roles.pop();
        return {roles}
    }
}

4、配合vue-router路由守卫使用

如果希望在进入新页面之前就确定好那些元素需要被屏蔽,v-roler本身提供了两个API用以随时获取当前可用的权限和更新权限,配合vue-router的路由守卫可以实现页面组件初始化前更新权限列表,保证在页面渲染时已经去屏蔽掉了无权限的元素。

import {updateRoles,getRoles} from "v-roler";
import VueRouter from "vue-router";

const routes = [
  { path: '/',name:'home', component: Home },
]
const router = VueRouter.createRouter({
    history:VueRouter.createWebHashHistory(),
    routes
})

router.beforeEach((to, from, next) => {
    // 获取当前v-roler中储存的所有权限
  const allRoles = getRoles();
  // 如果存在view权限,则用新的权限数组["add","delete","edit"]去更新v-roler的权限
  // 注意,updateRoles方法并不会删除初始化时声明的权限,只会更新后续通过其他方法新增的权限
  if(allRoles.includes("view")){
      updateRoles(["add","delete","edit"])
      // 更新完权限后再进入该页面
      next()
  }else{
      next({name:"home"})
  }
})

四、API参考

插件选项(Plugin Options)

name type required description
roles Array yes 初始化时作为基础的权限路由,如["musice-add","music-edit"]
directive string no 用户自定义的指令,如果不传,则默认使用v-can作为指令

示例:参考使用方法中的安装插件

全局API(Global API)

name param return required description
useRoler string[] [roles,resetRolesFunction] 参数非必须 当传入一个数组时,相当于在插件初始化时的数组基础上,新增权限列表。返回值是一个数组,第一个元素是当前可用的所有权限列表,第二个是重置当前权限列表的方法,参数是一个权限数组,示例参考使用hook更改权限
getRoles / string[] / 返回当前最新的所有权限,返回类型是一个数组
updateRoles string[] void yse 用传入的数组来重置更新当前的所有权限
> 注意:插件安装时初始化传入的权限数组是固定无法重置的,无论是hook还是updateRoles等方式都智能在初始权限的基础上累加或修改权限列表