• vue权限控制的想法


    前言

    最近做到了一个权限控制的功能。在这个功能中看到了这个功能的写法,了解到了这个权限控制的功能,也引发了思考。除了 v-if ,还有没有更好的,更直观的,更全局的写法呢?带着这个问题,我们先来看一下,这个权限数据的来源。

    权限来源

    获取数据的方法也很简单,就是后台接口请求数据。后端在登录后一次性返回所有的权限数据,然后全局 localStorage 或者 store 存储起来。如果发生了修改就可以及时的通知到全局,在使用获取的时候也方便快捷。代码如下:

    1. import { defineStore } from 'pinia'
    2. // 声明,初始化
    3. const defaultState = {
    4. permissions: {}, // 权限列表
    5. }
    6. // 设置state,存储
    7. function setData(obj) {
    8. Object.keys(obj).forEach((key) => {
    9. state[key] = obj[key]
    10. })
    11. // 每次改动更新缓存
    12. localStorage.setItem(LOCAL_STORAGE_NAME, JSON.stringify(toRaw(state)))
    13. }
    14. // 请求权限码
    15. async function getPermissionList() {
    16. const res = await ajaxStore.common.getPermissionList()
    17. if (res.data?.code === '0') {
    18. const arr = res.data?.data ?? []
    19. const obj = {}
    20. arr.forEach((item) => (obj[item.permissionCode] = item.permissionName))
    21. // 全局存储
    22. setData({ permissions: obj })
    23. return state.permissions
    24. } else {
    25. return null
    26. }
    27. }

    获取到数据以后,就可以来思考怎么使用这些数据。目前,所知的有3种权限控制方式,下面我们一个一个的来看。

    三种方法

    1. 函数方式

    这是我们最先想到的方法,也是最常用的方法。代码如下:

    1. <template>
    2. <div>
    3. <Tabs :data="tabConfigs"></Tabs>
    4. <NoPower v-if="!(tabConfigs && tabConfigs.length)"></NoPower>
    5. </div>
    6. </template>
    7. <script setup name="realestateWarning">
    8. // 获取 permissions 数据
    9. import useUser from '@/store/user'
    10. // 获取所有的菜单
    11. import { realestateWarningTabs } from '@/const/menu'
    12. const userInfo = useUser()
    13. // 过滤tab权限
    14. const tabConfigs = computed(() => {
    15. const { permissions } = userInfo ?? {}
    16. return (
    17. realestateWarningTabs.filter((item) => {
    18. item.label = item.text
    19. return permissions[item.permissionCode]
    20. }) ?? []
    21. )
    22. })
    23. </script>

    本质就是使用 一个 tabConfigs 来筛选需要显示哪些 tab,其中操作是从全局 store 中获取当前用户的权限码列表,然后判断其中是否存在当前需要的权限码,如果有对应的权限码,就加进来。

    2. 组件方式

    我们可以单独写一个组件,在组件内部进行权限的控制操作,主要是通过插槽的形式把内部需要展示的组件引入进来,在需要加权限的地方进行组件的引入,组件内部的逻辑和函数方式基本无异。这样就可以统一管理权限了,使用起来也比较方便。代码如下:

    1. <template>
    2. <div>
    3. <Permission :value="AAAAAA">
    4. <AAAAAA/>
    5. </Permission>
    6. <Permission :value="BBBBBB">
    7. <BBBBBB/>
    8. </Permission>
    9. <Permission :value="CCCCCC">
    10. <CCCCCC/>
    11. </Permission>
    12. </div>
    13. </template>
    14. <script>
    15. import { Permission } from './Permission';
    16. </script>
    1. <script>
    2. // 获取 permissions 数据
    3. import useUser from '@/store/user'
    4. // 获取所有的菜单
    5. import { realestateWarningTabs } from '@/const/menu'
    6. export default defineComponent({
    7. props: {
    8. value: {
    9. type: [Number, Array, String],
    10. default: '',
    11. },
    12. },
    13. setup(props, { slots }) {
    14. const userInfo = useUser()
    15. const { permissions } = userInfo ?? {}
    16. const { hasPermission } = usePermission();
    17. function renderAuth() {
    18. const { value } = props;
    19. if (!value) {
    20. return getSlot(slots);
    21. }
    22. return permissions[value] ? getSlot(slots) : null;
    23. }
    24. return () => {
    25. return renderAuth();
    26. };
    27. },
    28. });
    29. script>
    3. 指令方式

    指令方式就是自己写个指令,在需要的组件上使用指令就行了。如下:

    引用:

    1. <template>
    2. <div>
    3. <AAAAAA v-permission="AAAAAA"/>
    4. <BBBBBB v-permission="BBBBBB"/>
    5. <CCCCCC v-permission="CCCCCC"/>
    6. </div>
    7. </template>

    编写指令:

    1. import { createApp, reactive, watchEffect } from "vue"
    2. const codeList = reactive([1, 2, 3])
    3. const hasPermission = (value) => {
    4. return codeList.includes(value)
    5. }
    6. app.directive("permission", {
    7. updated(el, binding) {
    8. let update = () => {
    9. let valueNotChange = binding.value === binding.oldValue
    10. let oldHasPermission = hasPermission(binding.oldValue)
    11. let newHasPermission = hasPermission(binding.value)
    12. let permissionNotChange = oldHasPermission === newHasPermission
    13. if (valueNotChange && permissionNotChange) return
    14. if (newHasPermission) {
    15. addEl(el)
    16. } else {
    17. removeEl(el)
    18. }
    19. };
    20. if (el._watchEffect) {
    21. update()
    22. } else {
    23. el._watchEffect = watchEffect(() => {
    24. update()
    25. })
    26. }
    27. },
    28. })

    在绑定元素挂载后调用,使用 permissions 判断当前用户是否存在通过指令插入的按钮需要的权限码,如果不存在,直接移除绑定的元素。

    在实际的开发中也会有其他的控制方式,在各种论坛中也看到了,使用装饰器来做的,其实不管怎么做,都是为了抽离业务逻辑,是我们用起来跟简单为目的。

  • 相关阅读:
    CMSC5707-高级人工智能之音频信号预处理操作
    3-6数据链路层-广域网
    Qt通过Doc模式读取XML并设计一个增删改查方便的一个操作类
    SQL语句,存储过程,触发器
    揭秘YAML:Python中的PyYAML应用
    Vue_路由VueRoute
    【算法学习】-【双指针】-【有效三角形的个数】
    【Linux系统管理】14 日志管理
    SpringBoot文件上传
    第十三篇-Tesla P40+ModelScope+Gradio+QWen-14B-Int4
  • 原文地址:https://blog.csdn.net/develop_csdn/article/details/132711577