【Vue.js】v-hasPermission & v-show 不能正常显示的问题

使用 v-hasPermissionv-show 组合来控制按钮显示时,发现没有权限的按钮仍然能显示。
删除 v-show 的判断单独使用 v-hasPermission 时是可以正常根据权限来隐藏或显示的。

<el-tooltip v-hasPermission="['permission:reset-user-flag']" content="重置用户标志" v-show="row.flag !== 1" placement="left">
  <el-button type="primary" @click="resetUserFlag(row)">关键</el-button>
</el-tooltip>
  

解决方法很简单,只需要将 v-show 属性提到 v-hasPermission 前就可以了。

<el-tooltip v-show="row.flag !== 1" v-hasPermission="['permission:reset-user-flag']" content="重置用户标志" placement="left">
  <el-button type="primary" @click="resetUserFlag(row)">关键</el-button>
</el-tooltip>
  

附1. 自定义 Vue 权限指令

原文:https://blog.csdn.net/qq_36437172/article/details/102060050

在前端页面中,我们已经实现了通过不同用户获取不同的路由,以此渲染出不同的菜单列表功能,此外页面上的操作按钮也必须进行权限控制。正如前面所述,在登录成功后,系统会把用户的角色和权限信息存储到了内存中,所以我们可以通过这些信息结合 自定义Vue指令 的方式来实现按钮的权限控制。

目前支持的和权限相关的Vue指令有:

指令含义示例
v-hasPermission当用户拥有列出的权限的时候,渲染该元素<template v-hasPermission="'user:add','user:update'"><span>hello</span></template>
hasNoPermission当用户没有列出的权限的时候,渲染该元素<template v-hasNoPermission="'user:add','register'"><span>无操作权限</span></template>
  1. src/utils/permissionDirect.js 中定义如下代码:

    export const hasPermission = {
      install (Vue) {
        Vue.directive('hasPermission', {
          bind (el, binding, vnode) {
            let permissions = vnode.context.$store.state.account.permissions
            let value = binding.value.split(',')
            let flag = true
            for (let v of value) {
              if (!permissions.includes(v)) {
                flag = false
              }
            }
            if (!flag) {
              if (!el.parentNode) {
                el.style.display = 'none'
              } else {
                el.parentNode.removeChild(el)
              }
            }
          }
        })
      }
    }
      

    我们从 Vuex 中获取了用户所拥有的权限,然后判断这些权限中是否包含 user:add,如果不包含,则将对应的元素(el)移除或者隐藏。所以当用户没有 user:add 权限时,下面的按钮将不会被渲染在页面上:

    <template v-hasPermission="'user:add'"><button>新增用户</button></template>
      

    扩展:

    1. bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。

    2. 指令钩子函数会被传入以下参数:

      el : 指令所绑定的元素,可以用来直接操作 DOM 。
      binding : 一个对象,包含以下属性:
      name : 指令名,不包括 v- 前缀。
      value : 指令的绑定值,例如:v-my-directive="1 + 1" 中,绑定值为 2。
      oldValue : 指令绑定的前一个值,仅在 updatecomponentUpdated 钩子中可用。无论值是否改变都可用。
      expression : 字符串形式的指令表达式。例如 v-my-directive="1 + 1" 中,表达式为 "1 + 1"
      arg : 传给指令的参数,可选。例如 v-my-directive:foo 中,参数为 "foo"
      modifiers : 一个包含修饰符的对象。例如:v-my-directive.foo.bar 中,修饰符对象为 { foo: true, bar: true }
      vnodeVue 编译生成的虚拟节点。移步 VNode API 来了解更多详情。

  2. 要让自定义 Vue 指令生效,还需要在 src/utils/install.js 中将其添加到 Plugins 列表,只需在 main.js 文件中引入下列文件即可。

    import Vue from 'vue'
    import { hasPermission, hasNoPermission } from 'utils/permissionDirect'
    
    const Plugins = [ hasPermission, hasNoPermission]
    Plugins.map((plugin) => {
      Vue.use(plugin)
    })
    
    export default Vue