Vue + ElementUI的电商管理系统实例09 分配角色权限

1、弹出分配权限的对话框并请求权限数据

先给分配按钮添加点击事件:

<el-button size="mini" type="warning" icon="el-icon-setting"
              @click="showSetRightDialog(scope.row.id)">分配权限</el-button>

添加分配权限对话框:

<!--分配角色权限的对话框-->
<el-dialog title="分配权限" :visible.sync="setRightDialogVisible"
      width="50%">
      <!--内容主体区域-->
      111
      <!--底部按钮区域-->
      <span slot="footer" class="dialog-footer">
        <el-button @click="setRightDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="setRightDialogVisible = false">确 定</el-button>
      </span>
</el-dialog>

<script>
export default {
  data() {
    return {
       setRightDialogVisible: false, // 控制分配角色权限对话框是否显示
       rightsList: [] // 角色所有权限数据
    }
  },
  methods: {
     // 展示分配权限的对话框
    async showSetRightDialog(id) {
      this.setRightDialogVisible = true
      // 获取所有权限列表 树形
      const { data: res } = await this.$http.get('rights/tree')
      console.log(res)
      if (res.meta.status !== 200) {
        return this.$message.error('获取权限列表失败')
      }
      this.rightsList = res.data
    }
  }
}
</script>

2、分配并使用el-tree树形控件

先把Tree添加引入到element.js,这里就不写了。

然后找到el-tree的实例代码:show-checkbox 节点是否可被选择

<!--内容主体区域 树形控件-->
<el-tree :data="rightsList" :props="defaultProps" show-checkbox></el-tree>

<script>
export default {
  data() {
    return {
       // 树形控件的属性绑定对象
      treeProps: {
        label: 'authName',
        children: 'children'
      }
    }
  }
}
</script>

效果图:

3、优化树形控件的显示UI

node-key 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的

default-expand-all 是否默认展开所有节点

<!--内容主体区域 树形控件-->
<el-tree :data="rightsList" :props="treeProps" show-checkbox default-expand-all node-key="id"></el-tree>

4、加载当前角色的已有权限

default-checked-keys 默认勾选的节点的 key 的数组

<!--内容主体区域 树形控件-->
<el-tree :data="rightsList" :props="treeProps" show-checkbox default-expand-all :default-checked-keys="defKeys"
        node-key="id"></el-tree>

<script>
export default {
  data() {
    return {
       defKeys: [] // 默认选中的节点ID值数组
    }
  }
}
</script>

把权限的id放入到defKeys数组中。

点击分配权限按钮的同时,把当前角色已有的三级权限的id都放入到defKeys数组中。

// 展示分配权限的对话框
async showSetRightDialog(role) {
      // 获取所有权限列表 树形
      const { data: res } = await this.$http.get('rights/tree')
      // console.log(res)
      if (res.meta.status !== 200) {
        return this.$message.error('获取权限列表失败')
      }
      this.rightsList = res.data

      // 嵌套循环获取三级节点的id
      var arr = []
      // console.log(role.children)
      var children1 = role.children
      for (var i = 0; i < children1.length; i++) {
        var children2 = children1[i].children
        // console.log(children2)
        for (var j = 0; j < children2.length; j++) {
          var children3 = children2[j].children
          // console.log(children3)
          for (var k = 0; k < children3.length; k++) {
            arr.push(children3[k].id)
          }
        }
      }
      this.defKeys = arr

      this.setRightDialogVisible = true
},

也可以先创建一个递归函数:

// 通过递归的形式,获取角色下所有三级权限的id,并保存到defKeys数组中
getLeafKeys(node, arr) { // 节点 数组
      // 如果当前node节点不包含children属性,则是三级权限节点
      if (!node.children) {
        return arr.push(node.id)
      }
      // 循环node里的children数组,每循环一项拿到一个子节点item,在根据item再次调用递归函数getLeafKeys,
      // 然后把当前的item当做一个节点传进去,同时把arr传进去。只要递归完毕后,就把三级节点的id都保存到arr了
      node.children.forEach(item => this.getLeafKeys(item, arr))
}

然后调用递归函数:

// 展示分配权限的对话框
async showSetRightDialog(role) {
      // 获取所有权限列表 树形
      const { data: res } = await this.$http.get('rights/tree')
      console.log(res)
      if (res.meta.status !== 200) {
        return this.$message.error('获取权限列表失败')
      }
      this.rightsList = res.data

      // 递归获取三级节点的id
      this.getLeafKeys(role, this.defKeys)

      this.setRightDialogVisible = true
},

分配权限按钮加上scope.row:

<el-button size="mini" type="warning" icon="el-icon-setting"
      @click="showSetRightDialog(scope.row)">分配权限</el-button>

此时点击分配按钮,弹出的对话框如图:

5、小bug,在关闭分配权限对话框时重置defKeys数组为空

给对话框绑定close事件:

<!--分配角色权限的对话框-->
<el-dialog title="分配权限" :visible.sync="setRightDialogVisible" width="50%" @close="showSetRightDialogClosed">

showSetRightDialogCloseds事件:

// 监听 分配权限对话框的关闭事件
showSetRightDialogClosed() {
    this.defKeys = []
}

当然也可以在打开对话框的时候清空defkeys数组,意思是一样的。

6、调用api接口完成分配权限功能

角色授权接口,请求路径:roles/:roleId/rights,请求方法:post,参数rids  权限 ID 列表(字符串) 以 `,` 分割的权限 ID 列表(获取所有被选中、叶子节点的key和半选中节点的key, 包括 1,2,3级节点) 

rids  权限 ID 列表:就是说所有选中和半选中状态的id,然后以','分割

getCheckedKeys
若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点的 key 所组成的数组
(leafOnly) 接收一个 boolean 类型的参数,若为 true 则仅返回被选中的叶子节点的 keys,默认值为 false

getHalfCheckedKeys
若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点的 key 所组成的数组

给树形控件添加引用:

<!--内容主体区域 树形控件-->
<el-tree :data="rightsList" :props="treeProps" node-key="id" show-checkbox default-expand-all
        :default-checked-keys="defKeys" ref="treeRef"></el-tree>

给确定按钮添加点击事件:

<el-button type="primary" @click="allotRigths">确 定</el-button>

添加allotRigths事件:

// 点击按钮 给角色分配权限
async allotRigths(id) {
      const keys = [
        ...this.$refs.treeRef.getCheckedKeys(),
        ...this.$refs.treeRef.getHalfCheckedKeys()
      ]
      console.log(keys)
}

此时选择添加商品、商品修改、商品删除3个权限,点击确定,控制台会打印出keys数组,如下图:

然后要把keys数组的值形成一个以","拼接字符串:

const idStr = keys.join(',')

再调用角色授权接口,把Keys数组传递给rids参数:

还有请求路径要带角色ID,但是我们在确定按钮哪里获取不到角色ID,只能在点击分配按钮的时候,先把角色ID传出来

<script>
export default {
  data() {
    return {
       roleId: '' // 当前角色id
    }
  },
  methods: {
     // 展示分配权限的对话框
    async showSetRightDialog(role) {
      this.roleId = role.id // 获取角色id
      。。。
    }
}
</script>

然后请求接口:

// 点击按钮 给角色分配权限
async allotRigths() {
      const keys = [
        ...this.$refs.treeRef.getCheckedKeys(),
        ...this.$refs.treeRef.getHalfCheckedKeys()
      ]
      // console.log(keys)
      const idStr = keys.join(',')
      const { data: res } = await this.$http.post(`roles/${this.roleId}/rights`, { rids: idStr })
      if (res.meta.status !== 200) {
        return this.$message.error('更新角色权限失败!')
      }
      this.$message.success('更新角色权限成功!')
      this.getRolesList()
      this.setRightDialogVisible = false
}

效果图:

原文地址:https://www.cnblogs.com/joe235/p/12134057.html