eladmin按钮权限分配超详情很简单checkPermission和v-permission的区别

本文介绍了在Vue项目中使用Element-UI进行权限管理的方法,包括为不同用户分配不同权限,以及如何利用v-permission指令和checkPermission方法控制表格列的显示。在遇到v-permission无法删除表格空列的问题时,通过checkPermission解决,确保无权限的列不会显示。

前言

在最近的项目中,有对于不同用户分配不同权限的需求,以前写的时候知识跟着用,这次按照 登录-刷新-验证 打算自己去看一遍(使用element-ui)

上文总结

另一篇按钮权限分配我们说到了 v-permission 的用法和执行过程,先来个小总结

对于管理员

如果要让管理员拥有对某个表格的增删改权限
只需要在表格 v-permission 列表中添加 ‘admin’ 字段就可以了

<el-table-column
  v-permission="['admin', 'user:edit', 'user:del']"
  label="操作"
  align="center"
  fixed="right"
>
	<template slot-scope="scope">
	<udOperation
	  :data="scope.row"
	  :permission="permission"
	>
	</udOperation>
	</template>
</el-table-column>

对于普通用户

  1. 需要在 permission 中写上当前权限标识。
permission: {
 add: ['user:add'],
 edit: ['user:edit'],
 del: ['user:del']
}

  1. 然后在菜单页面,添加按钮,然后写上相应的权限标识。
    在这里插入图片描述

  2. 再在角色管理页面给相应用户分配这个权限。
    在这里插入图片描述

v-permission只能对按钮做判断么?

当然不是的,再来看这个自定义指令

inserted(el, binding, vnode) {
  // 解构赋值拿到v-permission绑定的值
  const { value } = binding
  // 获取gatters里面的roles(user下的roles)
  const roles = store.getters && store.getters.roles
  if (value && value instanceof Array && value.length > 0) {
    const permissionRoles = value
	// 判断roles里面是否含有v-permission绑定的值
    const hasPermission = roles.some(role => {
      return permissionRoles.includes(role)
    })
	// 如果该用户没有权限,就找到父节点,然后在父节点将次节点移除
    if (!hasPermission) {
      el.parentNode && el.parentNode.removeChild(el)
    }
  } else {
    throw new Error(`使用方式: v-permission="['admin','editor']"`)
  }
}

我们可以看到,v-permission 通过vuex拿到存储的用户所有权限和传进来的权限标识数组匹配,匹配到了就 return true,匹配不到就移除当前节点
所以,v-permission不只可以作用于按钮,可以使用在任意标签上(此处感谢远远学姐精炼的总结能力以及强大的实践能力)

碰到的问题

在处理表格时,使用v-permission并不能移除当前节点,按钮是没了,但是留下了空列

对此我打印发现,用在表格中时,他的父节点为null
这就不难解释为什么留下了空列了

checkPermission

对此,我们可以用 checkPermission 方法

此方法在 src/mixins
使用

  1. 在vueComponents中引入
import crud from '@/mixins/crud'
  1. 混入
mixins: [crud]
  1. 使用
checkPermission(['repay:edit','repay:sure'])

看实现过程

src/utils/permission.js

export default function checkPermission(value) {
  if (value && value instanceof Array && value.length > 0) {
    const roles = store.getters && store.getters.roles
    const permissionRoles = value

    const hasPermission = roles.some(role => {
      return permissionRoles.includes(role)
    })

    if (!hasPermission) {
      return false
    }
    return true
  } else {
    console.error(`need roles! Like v-permission="['admin','editor']"`)
    return false
  }
}

我们可以看到,checkPermission接收的是一个权限数组,还是去拉取当前用户所有权限,然后跟传进来的权限数组进行比对。有权限就return true,没有权限就return fakse

所以对于控制不同角色动态显示不同的列,可以使用 v-if+checkPermission

<el-table-column
  v-if="checkPermission(['repay:edit','repay:sure'])"
  label="操作"
  width="250px"
  align="center"
  fixed="right"
>
</el-table-column>
<think> 我们正在解决的是在Vue.js中v-permissionv-if指令冲突的问题。 问题分析: v-permission通常是自定义指令,用于根据用户权限控制元素的显示。 v-if是Vue内置指令,用于条件渲染。 冲突原因: 当两者同时作用于同一个元素时,可能会出现优先级问题或逻辑冲突。例如,v-permission控制显示,但v-if条件为false,元素不显示;或者反过来。 解决方案: 1. 避免在同一元素上同时使用v-permissionv-if。可以将v-if提升到外层包裹元素上,或者将权限判断条件判断合并。 2. 修改v-permission指令,使其能够融合条件判断(需要修改指令实现)。 3. 使用计算属性将权限条件合并为一个判断。 具体方法: 方法一:使用包裹元素 用一个元素(如div或template)包裹需要控制的元素,在包裹层使用v-permission,在内层使用v-if(或反过来)。 示例: ```html <template v-permission="['admin']"> <div v-if="condition"> 内容 </div> </template> ``` 方法二:合并条件到v-if 将权限检查作为条件的一部分,这样只需要使用v-if。 示例: ```html <div v-if="hasPermission('admin') && condition"> 内容 </div> ``` 在Vue实例中: ```javascript methods: { hasPermission(permission) { // 根据你的权限逻辑实现 return this.$store.state.permissions.includes(permission); } } ``` 方法三:自定义指令修改(高级) 修改v-permission指令,使其可以同时接受权限条件。这需要修改指令的定义。 例如,自定义指令可以这样定义(假设我们允许传递一个对象,包含权限条件): ```javascript Vue.directive('permission', { bind: function (el, binding, vnode) { const { permissions, condition } = binding.value; // 检查权限 const hasPermission = checkPermission(permissions); // 如果条件不满足或者没有权限,则隐藏元素 if (!hasPermission || (condition !== undefined && !condition)) { el.style.display = 'none'; } } }); ``` 使用: ```html <div v-permission="{ permissions: ['admin'], condition: someCondition }"> 内容 </div> ``` 方法四:使用计算属性 将权限条件合并为一个计算属性,然后使用v-if。 示例: ```html <div v-if="showContent"> 内容 </div> ``` ```javascript computed: { showContent() { return this.hasPermission('admin') && this.condition; } } ``` 推荐方法: 通常推荐方法二或方法四,因为它们更符合Vue的数据驱动理念,且不需要修改自定义指令。 注意事项: - 如果使用包裹元素,注意不要破坏HTML结构(比如使用template包裹不会增加额外节点)。 - 如果权限判断是异步获取的,需要确保在条件中使用时权限数据已经就绪。 总结:根据具体情况选择合适的方法,避免指令冲突。 相关问题: 1. Vue自定义指令v-permission如何实现? 2.Vue中如何全局管理用户权限? 3. v-ifv-show有什么区别? </think> 在Vue.js中解决`v-permission``v-if`指令冲突的问题,可以通过以下方法实现: ### 🛠️ 解决方案 #### 方法1:优先级分层(推荐) ```html <template> <!-- 外层用v-permission检查权限 --> <div v-permission="'add_user'"> <!-- 内层用v-if处理业务条件 --> <el-button v-if="isFormValid">提交</el-button> </div> </template> ``` **优点**:逻辑清晰,避免指令直接冲突 **原理**:通过DOM层级分离权限判断业务条件判断[^1] #### 方法2:自定义组合指令 ```javascript // main.js Vue.directive('permission-if', { inserted(el, binding, vnode) { const [permission, condition] = binding.value const hasPermission = checkPermission(permission) // 权限验证方法 if (!hasPermission || !condition) { el.parentNode.removeChild(el) } } }) ``` **使用方式**: ```html <button v-permission-if="['add_user', formValid]">提交</button> ``` #### 方法3:计算属性整合 ```javascript export default { computed: { showButton() { return this.$hasPermission('add_user') && this.formValid } } } ``` ```html <el-button v-if="showButton">提交</el-button> ``` ### ⚠️ 冲突原因 1. **执行顺序问题**:自定义指令`v-if`的生命周期钩子执行顺序不确定 2. **渲染机制冲突**:`v-if`直接操作DOM节点,而权限指令可能依赖虚拟DOM状态 3. **条件判断重叠**:两者都控制元素显示/隐藏,容易产生逻辑矛盾 ### 💡 最佳实践建议 1. **权限优先原则**:始终先进行权限校验,再进行业务条件判断 2. **避免同级使用**:禁止在同一元素上同时使用两个指令 ```html <!-- 错误用法 --> <button v-permission="'edit'" v-if="isActive">保存</button> ``` 3. **服务端兜底**:关键操作必须添加服务端权限验证,不依赖前端控制 ### 🌰 实际场景示例 ```html <template> <!-- 文件删除操作 --> <div v-permission="'file_delete'"> <el-popconfirm v-if="file.status !== 'locked'" @confirm="handleDelete" > <el-button slot="reference">删除文件</el-button> </el-popconfirm> </div> </template> ``` > 此实现保证:① 有权限的用户才看到按钮 ② 文件未锁定时才显示操作确认 [^1]: 基于Vue官方指令优先级设计文档Element-UI权限实践
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值