在实际开发中,会遇到很多的权限控制、资源位的场景,其实就是用来控制某个组件的展示与否,可以是一个按钮、一个报表、一个TAB页面等
例如下图,我想通过当前登录的用户控制谷歌的这个logo显示与否
因为设计到的权限、资源位控制比较多,如果单纯的使用v-if 进行组件的展示与否的判断,会导致在每个页面都需要重新写,重新从vuex或者pinia或者发起请求获取资源为列表,再通过当前用户判断是否有权限。
这就导致了两个问题:
1)代码冗余,难于维护
2)v-if中条件过多容易逻辑混乱
所以我们就可以通过自定义的指令进行控制,所谓自定义指令,其实就是写一个类似v-if的属性,通过我们自定义的逻辑判断达到组件展示与否的功能
首先再src下新建名为directive的文件夹,新建如下两个js文件
permission.js文件:
import {useSubscriber} from "@/store/index.js";
/**
* 权限控制指令
*/
export default {
mounted(el,binding){
// 首先判断是否使用自定义指令 若不使用(无值)则不进行校验
if(binding.value){
// 获取pinia中的用户信息
const subscriber = useSubscriber()
// 从用户信息中获取其包含的权限列表
const perms = subscriber.perms
// 判断权限列表中是否包含自定义指令输入的值
const flag = binding.value.some((item) => {
return perms.indexOf(item) > -1
})
// 如果不包含的话 则代表无权限,则删除该节点
if(!flag){
el.parentNode && el.parentNode.removeChild(el)
}
}
}
}
index.js文件:
import permission from "./permission"
const directives = {
permission
}
// 注册指令
export default {
install(Vue){
Object.keys(directives).forEach(key=>{
Vue.directive(key,directives[key])
})
}
}
然后我们再main.js中增加
import directive from "./directive/index.js";
app.use(router)
.use(store)
// 挂到app上
.use(directive)
.use(components).mount('#app')
然后就可以需要使用的页面上通过v-permission="['']"使用了
我在网上看到些方法,里面写的是将该节点的display属性置为none,但是这样的话就会导致更改页面源码,将该组件再展示出来,所以建议还是直接删除节点。