• 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

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

        支付宝                  微信

       

  • 相关阅读:
    (紫书,感谢作者)第7章暴力求解法
    明日更新
    明天更新
    UVa11882最大的数(dfs+剪枝)
    UVa12569树上的机器人的规划
    es6中的reduce方法?
    浏览器是如何渲染页面的?
    判断是不是一个数组?
    判断是否是一个数组?
    var与let的区别?
  • 原文地址:https://www.cnblogs.com/sauronblog/p/11617263.html
Copyright © 2020-2023  润新知