Vue电商后台管理系统项目第5篇-角色列表的增删改查&&角色授权

角色列表的增删改查

1.添加角色

先根据API文档编写接口;

// 添加角色
export const addRolesApi = (data) => {
  return axios({
    method: 'post',
    url: 'roles',
    data
  })
}

在角色组件内引用,然后给 添加角色 按钮绑定一个点击事件addRolesClick;

<!-- 添加角色 -->
<el-button type="success" plain @click="addRolesClick">添加角色</el-button>

找到Element-UI中的Dialog组件,添加到页面中;

<!-- 添加角色 -->
    <el-dialog title="添加角色" :visible.sync="addRolesDialogFormVisible">
      <el-form :model="addRolesForm" label-width="120px" ref="addRolesForm" :rules="rules">
        <el-form-item label="角色名称" prop="roleName">
          <el-input v-model="addRolesForm.roleName" autocomplete="off"></el-input>
        </el-form-item>

        <el-form-item label="角色描述" prop="roleDesc">
          <el-input v-model="addRolesForm.roleDesc" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="addRolesDialogFormVisible = false;$refs.addRolesForm.resetFields()">取 消</el-button>
        <el-button type="primary" @click="addRolesConfirm">确 定</el-button>
      </div>
    </el-dialog>

参数说明:

  1. :visible.sync="addRolesDialogFormVisible"    // 是否隐藏组件,接收一个布尔值
  2. :model    // 绑定的数据对象
  3. :rules="rules" // 验证规则
  4. prop="roleName"   // 要校验的字段
  5. v-model="addRolesForm.roleName"    // 双向数据绑定

业务逻辑和前面的用户管理=>用户列表的增删改查的业务逻辑都是一样的,用户输入数据后校验是否合法,合法之后发送请求然后刷新数据。

角色列表的删除指定权限(重点)

添加绑定事件

删除有两种:

  1. 删除三级权限:就是删除当前这一个三级权限
  2. 删除二级或一级权限:删除二级权限,对应的三级权限也被删除,同样的,删除一级权限对应的二级权限也将被删除
查阅接口文档,分析删除业务的组件内的处理,在组件内部我们需要获取到两个值:roleid(角色id),rightid(权限id)
实现接口方法
在vue组件中绑定事件,发起请求,记得传递两个参数
难点:删除之后的数据刷新
  1. 我们可以重新加载整个数据,但是这样会造成极不好的用户体验:因为展开行会合并
  2. 我们期望:能不能只刷新当前行数据,具体的说是能不能只刷新当前展开行数据?

解决:只刷新当前展开行的数据

  1. 我们发现,删除权限之后的返回值中有一个Data属性,这个data就是实现删除操作之后这个角色还拥有的权限数据

  2. 所以:我们可以直接将返回值中的Data覆盖这个展开行的数据源(scope.row.children)

  3. scope.row.children = res.data.data

@close='deleteright(scope.row,third.id)'
----------------------------------------
// 删除指定权限
deleteright (row, rightid) {
    deleteRightById(row.id, rightid)
        .then(res => {
        console.log('--------------')
        console.log(res)
        console.log('--------------')
        if (res.data.meta.status === 200) {
            this.$message({
                type: 'success',
                message: res.data.meta.msg
            })
            // 数据的刷新
            row.children = res.data.data
        }
    })
}

最终的模板代码:

<el-table-column type="expand">
    <!-- 展开的时候,template模板中的结构就是展开行的内容 -->
    <template slot-scope="scope">
        <!-- 遍历数据行对象的children -->
        <el-row v-for="first in scope.row.children" :key="first.id" style='margin-bottom:10px;border-bottom:1px dashed #ccc'>
            <el-col :span="4">
                <el-tag closable type="success"  @close='deleteright(scope.row,first.id)' v-if='first.children.length !== 0'>{{first.authName}}</el-tag>
            </el-col>
            <el-col :span="20">
                <el-row v-for='second in first.children' :key='second.id' style='margin-bottom:10px;' >
                    <el-col :span='4'>
                        <el-tag closable type="info"  @close='deleteright(scope.row,second.id)'  v-if='second.children.length !== 0'>{{second.authName}}</el-tag>
                    </el-col>
                    <el-col :span='20'>
                        <el-tag closable type="danger" v-for='third in second.children' :key='third.id' style='margin:0 4px 4px 0' @close='deleteright(scope.row,third.id)'>{{third.authName}}</el-tag>
                    </el-col>
                </el-row>
            </el-col>
        </el-row>
        <el-row>
            <el-col :span="24" v-if='scope.row.children.length === 0'>没有任何的权限数据,请先添加</el-col>
        </el-row>
    </template>
</el-table-column>

角色权限分配

分配权限弹出框的添加

在弹出框添加一个树形组件

  1. 找到组件,添加结构

  2. 分析树形组件的属性

  3. 动态加载所有权限数据

  4. 实现树形组件 节点的默认选中:获取当前角色所拥有的权限id

  5. 实现权限的设置:获取到当前用户所选择的所有权限所对应的id,并且拼接为,分隔的字符串格式

步骤:

  1. 分配权限弹出框的添加

  2. 树形组件的添加:默认展开+带复选框+默认选中

<el-tree
        :data="data2" // 数据源
        show-checkbox // 显示复选框
        node-key="id" //每个树节点用来作为唯一标识的属性,整棵树应该是唯一的,后期这个值就应该绑定为当前权限对象数据中的权限id
        :default-expanded-keys="[2, 3]" // 默认展开的节点
        :default-expand-all='true' // 默认展开所有节点
        :default-checked-keys="[5]" // 默认勾选的节点的 key 的数组
        :props="defaultProps" // 当前节点的配置,如你想展示什么数据,背后的value。。,子级数据
      ></el-tree>

树形组件的常用属性

<el-tree
        :data="rightList" // 数据源
        show-checkbox // 显示复选框
        node-key="id" //每个树节点用来作为唯一标识的属性,整棵树应该是唯一的,后期这个值就应该绑定为当前权限对象数据中的权限id
        :default-expand-all='true' // 默认展开所有节点
        :default-checked-keys="rightListByRole" // 默认勾选的节点的 key 的数组
        :props="defaultProps" // 当前节点的配置,如你想展示什么数据,背后的value。。,子级数据
      ></el-tree>
---------
defaultProps:{
    label:authName,
    chilren:children
}

数据和树形组件对应,显示权限动态数据

// 打开授权对话框
showGrantDialog () {
    this.grantdialogFormVisible = true
    // 获取所有权限数据
    getAllRightList('tree')
        .then(res => {
        console.log(res)
        this.rightList = res.data.data
    })
}

让树形组件有默认节点选择

  1. 选中子节点,父级节点也会被选中

  2. 我们只需要获取最下面一层的节点所对应的权限id

  3. 一级权限下不一定有二级权限,同样的,二级权限下不一定有三级权限--判断

  4. 我们得遍历当前角色所拥有的权限,获取到所有的权限id(最后一级)

// 获取当前角色所拥有的所有权限id
// 先将上一个角色的权限id数组清空
this.checkedArr.length = 0
row.children.forEach((first) => {
    if (first.children.length > 0) {
        // 遍历二级权限
        first.children.forEach(second => {
            if (second.children.length > 0) {
                // 遍历三级权限
                second.children.forEach(third => {
                    this.checkedArr.push(third.id)
                })
            }
        })
    }
})

实现角色授权的提交

  • 分析接口文档,想清楚接口到底需要什么

  • 我们如何获取接口所需要的参数?

  • 我们观察数据表的结构,我们发现,在存储三级权限的时候,它还同时存储着二级权限和一级权限

  • 所以我们有一个现实的需求:我们在获取权限id的时候,应该获取一个完整的拥有层次结构的id:(一级权限,二级权限,三级权限)

获取权限id: 为tree添加一个ref属性

  1. this.$refs.tree.getCheckedKeys():获取当前被选中的复选框所对应的key(node-key="id")
  2. 这个场合不要使用getCheckedKeys,因为当不是所有三级权限都被选中的情况下,它不能获取到二级权限和一级权限所对应的id
  3. this.$refs.tree.getCheckedNodes():可以获取到当前节点对象,这个对象中包含当前节点所对应的权限数据对象,这个对象中有完整的父级权限id

添加接口方法

// 角色授权
export const grantRightByRoleId = (roleid, rids) => {
  return axios({
    method: 'post',
    url: `roles/${roleid}/rights`,
    data: { rids: rids }
  })
}

实现授权提交

// 实现角色授权提交
grantSubmit () {
    // var arr = this.$refs.tree.getCheckedKeys()
    var arr = this.$refs.tree.getCheckedNodes()
    // [authName: "添加订单",id: 109,path: (...),pid: "107,102"]
    console.log(arr)
    // 我们需要的是每个权限所对应的id,同时包含它们的父级id
    // 1.遍历Arr,获取里面的两个值:id   pid  ,遍历:我需要遍历拼接后的结果["109,107,102",'154,107,102']
    // 它可以将回调函数的操作结果存储到map函数内部所创建的数组中,当遍历完之后再将其返回
    var temp = arr.map(value => {
        return value.id + ',' + value.pid
    })
    // ["109,107,102", "154,107,102"]
    console.log(temp)
    // 去除重复值--数组才能去重
    // 将数组拼接为字符串 “109,107,102,154,107,102"
    var str = temp.join(',')
    console.log(str)
    console.log(str.split(','))
    // 数组去重.new Set可以创建一个set对象,同时去除重复值
    var obj = new Set(str.split(','))
    console.log(obj)
    // 最终需要一个去除了重复值的数组,...可以将对象中的数据一个一个展开
    var final = [...obj]
    console.log(final.join(','))

    // 调用接口方法实现角色授权
    grantRightByRoleId(this.roleId, final.join(','))
        .then(res => {
        console.log(res)
    })
}

具体效果和业务逻辑代码还是直接从github上把项目拉下来细细研究吧:https://github.com/C4az6/vue_manage_system.git

如果您喜欢这篇文章,可以打赏点钱给我 :)

    支付宝                  微信

   

猜你喜欢

转载自www.cnblogs.com/sauronblog/p/11617263.html