ElementUI中Tree组件使用

news2024/9/23 13:25:36

       首先官网上的树形控件教程地址为Element - The world's most popular Vue UI framework

案例一:

要实现这种类型的树控件,并且后边相关操作:

1.1后端准备工作

 首先,数据库表为:

 查询接口返回的实体类为:

@Data
@NoArgsConstructor
@RequiredArgsConstructor // 有参构造
@EqualsAndHashCode(callSuper = false ,of = "name")// 表示以name去重写的Equals和HashCode
@Accessors(chain = true)
@TableName("t_department")
@ApiModel(value="Department对象", description="")
public class Department implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "部门名称")
    @Excel(name = "部门")
    @NonNull
    private String name;

    @ApiModelProperty(value = "父id")
    private Integer parentId;

    @ApiModelProperty(value = "路径")
    private String depPath;

    @ApiModelProperty(value = "是否启用")
    private Boolean enabled;

    @ApiModelProperty(value = "是否上级")
    private Boolean isParent;

    @ApiModelProperty(value = "子部门列表")
    @TableField(exist = false)
    private List<Department> children;

    @ApiModelProperty(value = "返回结果,存储过程使用")
    @TableField(exist = false)
    private Integer result;

}

查询接口返回的数据格式:通过属性 children来判断是否有子节点

[
  {
    "id": 1,
    "name": "股东会",
    "parentId": -1,
    "depPath": ".1",
    "enabled": true,
    "isParent": true,
    "children": [
      {
        "id": 2,
        "name": "董事会",
        "parentId": 1,
        "depPath": ".1.2",
        "enabled": true,
        "isParent": true,
        "children": [
          {
            "id": 3,
            "name": "总办",
            "parentId": 2,
            "depPath": ".1.2.3",
            "enabled": true,
            "isParent": true,
            "children": [
              {
                "id": 4,
                "name": "财务部",
                "parentId": 3,
                "depPath": ".1.2.3.4",
                "enabled": true,
                "isParent": false,
                "children": [],
                "result": null
              },
              {
                "id": 5,
                "name": "市场部",
                "parentId": 3,
                "depPath": ".1.2.3.5",
                "enabled": true,
                "isParent": true,
                "children": [
                  {
                    "id": 6,
                    "name": "华东市场部",
                    "parentId": 5,
                    "depPath": "1.2.3.5.6",
                    "enabled": true,
                    "isParent": true,
                    "children": [
                      {
                        "id": 8,
                        "name": "上海市场部",
                        "parentId": 6,
                        "depPath": "1.2.3.5.6.8",
                        "enabled": true,
                        "isParent": false,
                        "children": [],
                        "result": null
                      }
                    ],
                    "result": null
                  },
                  {
                    "id": 7,
                    "name": "华南市场部",
                    "parentId": 5,
                    "depPath": "1.2.3.5.7",
                    "enabled": true,
                    "isParent": false,
                    "children": [],
                    "result": null
                  },
                  {
                    "id": 9,
                    "name": "西北市场部",
                    "parentId": 5,
                    "depPath": ".1.2.3.5.9",
                    "enabled": true,
                    "isParent": true,
                    "children": [
                      {
                        "id": 10,
                        "name": "贵阳市场",
                        "parentId": 9,
                        "depPath": ".1.2.3.5.9.10",
                        "enabled": true,
                        "isParent": true,
                        "children": [
                          {
                            "id": 11,
                            "name": "乌当区市场",
                            "parentId": 10,
                            "depPath": ".1.2.3.5.9.10.11",
                            "enabled": true,
                            "isParent": false,
                            "children": [],
                            "result": null
                          }
                        ],
                        "result": null
                      }
                    ],
                    "result": null
                  }
                ],
                "result": null
              },
              {
                "id": 12,
                "name": "技术部",
                "parentId": 3,
                "depPath": ".1.2.3.12",
                "enabled": true,
                "isParent": false,
                "children": [],
                "result": null
              },
              {
                "id": 13,
                "name": "运维部",
                "parentId": 3,
                "depPath": ".1.2.3.13",
                "enabled": true,
                "isParent": false,
                "children": [],
                "result": null
              }
            ],
            "result": null
          }
        ],
        "result": null
      },
      {
        "id": 150,
        "name": "aaa",
        "parentId": 1,
        "depPath": ".1.150",
        "enabled": true,
        "isParent": true,
        "children": [
          {
            "id": 151,
            "name": "abbb",
            "parentId": 150,
            "depPath": ".1.150.151",
            "enabled": true,
            "isParent": false,
            "children": [],
            "result": null
          }
        ],
        "result": null
      },
      {
        "id": 154,
        "name": "ccc",
        "parentId": 1,
        "depPath": ".1.154",
        "enabled": true,
        "isParent": false,
        "children": [],
        "result": null
      },
      {
        "id": 157,
        "name": "dddd",
        "parentId": 1,
        "depPath": ".1.157",
        "enabled": true,
        "isParent": false,
        "children": [],
        "result": null
      }
    ],
    "result": null
  }
]

1.2前端代码

从官网上复制一个模板过来,搜索的话,直接往下找一个有搜索框的,把搜索框复制过来,复制好就可以开始修改,写增删改查的方法调用了。

 写好的代码如下:

<template>
  <div style="width: 550px;">
    <el-input
      placeholder="请输入部门名称进行搜索..."
      prefix-icon="el-icon-search"
      v-model="filterText">
    </el-input>

    <el-tree
      :data="deps"
      :props="defaultProps"
      :filter-node-method="filterNode"
      :expand-on-click-node="false"
      ref="tree">
      <!-- slot-scope可以自定义树节点里的内容,node当前节点的node对象,data后端对应返回的数据 -->
      <span class="custom-tree-node" slot-scope="{ node, data }" style="display:flex; justify-content: space-between;width: 100%;">
        <span>{{ data.name }}</span>
        <span>
          <el-button
            type="primary"
            size="mini"
            class="depBtn"
            @click="() => showAddDep(data)">
            添加部门
          </el-button>
          <el-button
            type="danger"
            size="mini"
            class="depBtn"
            @click="() => deleteDep(data)">
            删除部门
          </el-button>
        </span>
      </span>
    </el-tree>

    <!-- 添加部门的弹出框 -->
    <el-dialog
      title="添加部门"
      :visible.sync="dialogVisible"
      width="30%">
      <div>
        <table>
          <tr>
            <td><el-tag>上级部门</el-tag></td>
            <td><el-tag>{{pname}}</el-tag></td>
          </tr>
          <tr>
            <td><el-tag>部门名称</el-tag></td>
            <td><el-input v-model="dep.name" placeholder="请输入部门名称..."></el-input></td>
          </tr>
        </table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="doAddDep">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>

<script>
export default {
    data(){
      return{
        // 树的搜索条件
        filterText: '',
        // 树的数据
        deps: [],
        // 树的配置
        defaultProps: {
          children: 'children',
          label: 'name'
        },
        // 添加弹出框
        dialogVisible: false,
        // 添加的部门数据
        dep:{
          name:'',
          parentId: -1
        },
        // 上级部门名称
        pname: ''
      }
    },
    mounted(){
      this.initDeps();
    },
    methods: {
      // 初始化数据
      initDeps(){
        this.getRequest('/system/basic/department/').then(resp=>{
          this.deps = resp;
        })
      },
      // 树的搜索
      filterNode(value, data) {
        if (!value) return true;
        return data.name.indexOf(value) !== -1;
      },
      // 添加弹框
      showAddDep(data){
        console.log(data)
        this.dep.parentId = data.id;
        this.pname = data.name;
        this.dialogVisible = 'true'
      },
      // 添加
      doAddDep(){
        this.postRequest('/system/basic/department/',this.dep).then(resp=>{
          if(resp.code==200){
            resp.obj.children = []
            this.addDep2Deps(this.deps,resp.obj);
            this.initDep();
            this.dialogVisible = false;
          }
        })
      },
      initDep(){
        this.dep = {
          name: '',
          parentId: -1
        }
        this.panme = ''
      },
      // 添加成功后手动的给树加数据
      addDep2Deps(deps,dep){
        for(let i = 0; i<deps.length; i++){
          let d= deps[i];
          if(d.id == dep.parentId){
            d.children = d.children.concat(dep);
            if(d.children.length>0){
              d.isParent = true;
            }
            return;
          }else{
            // 递归
            this.addDep2Deps(d.children,dep);
          }
        }
      },
      // 删除
      deleteDep(data){
        console.log(data)
        if(data.isParent){
          this.$message.error("父部门无法删除");
        }else{
          this.$confirm('此操作将永久['+data.name+']部门, 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            this.deleteRequest('/system/basic/department/'+data.id).then(resp=>{
              if(resp.code==200){
                this.removeDepFromDeps(null,this.deps,data.id);
              }
            })
          }).catch(() => {
            this.$message({
              type: 'info',
              message: '已取消删除'
            });          
          });
        }
      },
      // 手动删除  (父部门,总部门数据,要删除的部门id)
      removeDepFromDeps(p,deps,id){
        for(let i=0; i<deps.length; i++){
          let d = deps[i];
          if(d.id==id){
            deps.splice(i,1);
            if(deps.length==0){
              p.isParent = false;
            }
            return;
          }else{
            this.removeDepFromDeps(d,d.children,id);
          }
        }
      }
    },
    watch: {
      filterText(val) {
        this.$refs.tree.filter(val);
      }
    }
}
</script>

<style>
.depBtn{
  padding: 3px;
}
</style>

需要注意的是:

1:树组件中    :data="deps" 加载树组建的数据。:props="defaultProps" 加载树组件的配置,其中label是给个枝叶的名字对应的字段,children是子节点对应的字段。:filter-node-method="filterNode" 树组件的搜索,filterNode过滤的回调,这个官网拷贝即可。:expand-on-click-node="false" 关闭点击折叠,只有点击前面的小三角才能展开折叠。

2:搜索框绑定的数据filterText,下面监听这个数据的改变,如果改变了,就调用树的filter方法(this.$refs.tree.filter(val);),进行过滤,这个方法的回调在树组件的属性中定义:filter-node-method="filterNode" ,也就是输入框值改变了,会去掉filterNode这个方法,这个方法传入两个值,value是文本框输入值,data是树组件的数据,value为空直接返回,不为空则过滤。

3: 添加部门的时候,添加成功后不能单纯的掉接口,重新请求一次树中的数据,这样的话,每添加一个部门,整个树就会折叠起来。这时候就需要不调接口请求新的数据,在js中操作树中的数据this.deps,让它和数据库保持同步。首先在成功后调用方法: addDep2Deps(deps,dep)  这个方法第一个参数是整个树中的数据,第二个参数是新添加的树的数据(这个数据是添加成功接口回显的数据,也就是添加的这条记录信息)在这个方法中,会循环,找到对应的父节点,给它的子节点拼接数据,修改父节点isParent属性(是否有孩子),之后就一直递归,知道添加完成为止。这个数据添加成功后,清空弹出框中输入的信息,关闭弹出框。

4:删除操作,同样,删除时也要手动的在js中把这条数据删除,不能请求新数据,请求新数据会导致树整个关闭,用户体验十分不好,需要在js中把树中的数据和数据库中进行同步。

调用接口删除成功后,调用removeDepFromDeps(p,deps,id)方法,在js中进行数据删除,调用时,第一个参数传null表示从顶层节点开始往下找,第二个参数是树的数据,第三个参数是要删除部门的id。同样进行循环,添加中比较的是父节点的id,删除是,比较的就是这个叶子的id,如果相同,那就删除,同时,判断把这个叶子删掉后,这个枝下面还有没有叶子,因为有叶子的枝是不能删除的,所以要再判断一下修改isParent的状态,之后还是一样,在一层中没有查询到的话,就递归到下一层去找。

案例二

这种前面带有选择框的,进行授权操作 

2.1后端准备

对应的数据库表

 对应的实体类:

@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("t_menu")
@ApiModel(value="Menu对象", description="")
public class Menu implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "url")
    private String url;

    @ApiModelProperty(value = "path")
    private String path;

    @ApiModelProperty(value = "组件")
    private String component;

    @ApiModelProperty(value = "菜单名")
    private String name;

    @ApiModelProperty(value = "图标")
    private String iconCls;

    @ApiModelProperty(value = "是否保持激活")
    private Boolean keepAlive;

    @ApiModelProperty(value = "是否要求权限")
    private Boolean requireAuth;

    @ApiModelProperty(value = "父id")
    private Integer parentId;

    @ApiModelProperty(value = "是否启用")
    private Boolean enabled;

    @ApiModelProperty(value = "子菜单")
    @TableField(exist = false) // 告诉mybatisplus这个字段不在表中,查询的时候不要去查
    private List<Menu> children;

    @ApiModelProperty(value = "角色列表")
    @TableField(exist = false)
    private List<Role> roles;

}

 查询接口返回的数据

{
  "code": 200,
  "message": "查询成功",
  "obj": [
    {
      "id": 1,
      "url": null,
      "path": null,
      "component": null,
      "name": "所有",
      "iconCls": null,
      "keepAlive": null,
      "requireAuth": null,
      "parentId": null,
      "enabled": null,
      "children": [
        {
          "id": 2,
          "url": null,
          "path": null,
          "component": null,
          "name": "员工资料",
          "iconCls": null,
          "keepAlive": null,
          "requireAuth": null,
          "parentId": null,
          "enabled": null,
          "children": [
            {
              "id": 7,
              "url": null,
              "path": null,
              "component": null,
              "name": "基本资料",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 8,
              "url": null,
              "path": null,
              "component": null,
              "name": "高级资料",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            }
          ],
          "roles": null
        },
        {
          "id": 3,
          "url": null,
          "path": null,
          "component": null,
          "name": "人事管理",
          "iconCls": null,
          "keepAlive": null,
          "requireAuth": null,
          "parentId": null,
          "enabled": null,
          "children": [
            {
              "id": 9,
              "url": null,
              "path": null,
              "component": null,
              "name": "员工资料",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 10,
              "url": null,
              "path": null,
              "component": null,
              "name": "员工奖惩",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 11,
              "url": null,
              "path": null,
              "component": null,
              "name": "员工培训",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 12,
              "url": null,
              "path": null,
              "component": null,
              "name": "员工调薪",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 13,
              "url": null,
              "path": null,
              "component": null,
              "name": "员工调动",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            }
          ],
          "roles": null
        },
        {
          "id": 4,
          "url": null,
          "path": null,
          "component": null,
          "name": "薪资管理",
          "iconCls": null,
          "keepAlive": null,
          "requireAuth": null,
          "parentId": null,
          "enabled": null,
          "children": [
            {
              "id": 14,
              "url": null,
              "path": null,
              "component": null,
              "name": "工资账套管理",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 15,
              "url": null,
              "path": null,
              "component": null,
              "name": "员工账套设置",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 16,
              "url": null,
              "path": null,
              "component": null,
              "name": "工资表管理",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 17,
              "url": null,
              "path": null,
              "component": null,
              "name": "月末处理",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 18,
              "url": null,
              "path": null,
              "component": null,
              "name": "工资表查询",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            }
          ],
          "roles": null
        },
        {
          "id": 5,
          "url": null,
          "path": null,
          "component": null,
          "name": "统计管理",
          "iconCls": null,
          "keepAlive": null,
          "requireAuth": null,
          "parentId": null,
          "enabled": null,
          "children": [
            {
              "id": 19,
              "url": null,
              "path": null,
              "component": null,
              "name": "综合信息统计",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 20,
              "url": null,
              "path": null,
              "component": null,
              "name": "员工积分统计",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 21,
              "url": null,
              "path": null,
              "component": null,
              "name": "人事信息统计",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 22,
              "url": null,
              "path": null,
              "component": null,
              "name": "人事记录统计",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            }
          ],
          "roles": null
        },
        {
          "id": 6,
          "url": null,
          "path": null,
          "component": null,
          "name": "系统管理",
          "iconCls": null,
          "keepAlive": null,
          "requireAuth": null,
          "parentId": null,
          "enabled": null,
          "children": [
            {
              "id": 23,
              "url": null,
              "path": null,
              "component": null,
              "name": "基础信息设置",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 24,
              "url": null,
              "path": null,
              "component": null,
              "name": "系统管理",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 25,
              "url": null,
              "path": null,
              "component": null,
              "name": "操作日志管理",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 26,
              "url": null,
              "path": null,
              "component": null,
              "name": "操作员管理",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 27,
              "url": null,
              "path": null,
              "component": null,
              "name": "备份恢复数据库",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            },
            {
              "id": 28,
              "url": null,
              "path": null,
              "component": null,
              "name": "初始化数据库",
              "iconCls": null,
              "keepAlive": null,
              "requireAuth": null,
              "parentId": null,
              "enabled": null,
              "children": null,
              "roles": null
            }
          ],
          "roles": null
        }
      ],
      "roles": null
    }
  ]
}

2.2前端代码

<template>
  <div>
    <!-- 添加角色  -->
    <div class="permissManaTool">
        <el-input size="small" placeholder="请输入角色英文名" v-model="role.name">
          <template slot="prepend">ROLE_</template>
        </el-input>
        <el-input size="small" placeholder="请输入角色中文名" v-model="role.nameZh" @keydown.enter.native="addRole"></el-input>
        <el-button size="small" type="primary" icon="el-icon-plus" @click="addRole">添加角色</el-button>
    </div>
    <!-- 手风琴  -->
    <div style="margin-top:10px; width:660px">
      <el-collapse v-model="activeName" accordion @change="change">
        <el-collapse-item :title="r.nameZh" :name="r.id" v-for="(r,index) in roles" :key="index">
          <!-- 卡片 -->
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span>可访问资源</span>
              <el-button style="float: right; padding: 3px 0; color: #ff0000;" type="text" icon="el-icon-delete" @click="doDeleteRole(r)"></el-button>
            </div>
            <div>
              <!-- 树 -->
              <el-tree 
                show-checkbox
                node-key="id"
                ref="tree"
                :key="index"
                :default-checked-keys="selectMenus" 
                :data="allMenus" :props="defaultProps"></el-tree>
                <div style="display:flex; justify-content: flex-end">
                  <el-button size="mini" @click="cancelUpdate">取消修改</el-button>
                  <el-button size="mini" type="primary" @click="doUpdate(r.id,index)">确定修改</el-button>
                </div>
            </div>
          </el-card>
        </el-collapse-item>
      </el-collapse>
    </div>
  </div>
</template>

<script>
export default {
    data(){
      return{
        role:{
          name:'',
          nameZh:''
        },
        activeName : '-1',
        roles:[],
        allMenus: [],
        // 树菜单的属性,children子菜单的属性,label显示出来的名字,都是后端接口返回来的字段名字
        defaultProps: {
          children: 'children',
          label: 'name'
        },
        // 树中选中的节点
        selectMenus: []
      }
    },
    mounted(){
      this.initRoles();
      
    },
    methods:{
      // 初始化所有菜单
      initAllMenus(){
        this.getRequest('/system/basic/permiss/menus').then(resp=>{
          if(resp.code==200){
            this.allMenus = resp.obj;
          }
        })
      },
      // 根据角色id获取菜单
      initSelectdMenus(rid){
        this.getRequest('/system/basic/permiss/mid/'+rid).then(resp=>{
          if(resp.code==200){
            this.selectMenus = resp.obj;
          }
        })
      },
      // 获取角色列表
      initRoles(){
        this.getRequest('/system/basic/permiss/').then(resp=>{
          if(resp.code==200){
            this.roles = resp.obj;
          }
        })
      },
      // 手风琴点击事件,展开rid是每个name,name对应着后端字段id,关闭时rid为空
      change(rid){
        if(rid){
          this.initAllMenus();
          this.initSelectdMenus(rid);
        }
      },
      // 修改角色权限 
      doUpdate(rid,index){
        // 拿到这个手风琴下面的树
        let tree = this.$refs.tree[index];
        // 传true只打印叶子节点的id
        let selectedKeys = tree.getCheckedKeys(true);
        let url = '/system/basic/permiss/?rid='+ rid;
        selectedKeys.forEach(key => {
          url += '&mids='+ key;
        });
        this.putRequest(url).then(resp=>{
          if(resp.code==200){
            this.activeName = '-1'
          }
        })
      },
      cancelUpdate(){
        this.activeName = '-1'
      },
      // 添加角色
      addRole(){
        if(this.role.name && this.role.nameZh){
          this.postRequest('/system/basic/permiss/',this.role).then(resp=>{
            if(resp.code==200){
              this.initRoles();
              this.role.name = '';
              this.role.nameZh = '';
            }
          })
        }else{
          this.$message.error("所有字段不能为空");
        }
      },
      // 删除角色
      doDeleteRole(role){
        this.$confirm('此操作将永久删除'+role.nameZh+'角色, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.deleteRequest('/system/basic/permiss/role/'+r.id).then(resp => {
            if(resp.code == 200){
              
              this.initRoles();
            }else{
              this.$message.error(resp.message)
            }
          })
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });          
        });
      }
    }
}
</script>

<style>
.permissManaTool{
  display: flex;
  justify-content: flex-start;
}
.permissManaTool .el-input{
  width: 300px;
  margin-right: 10px;
}
</style>

值得注意的是:

1:每个角色下面展开的权限树列表用的是手风琴组件(折叠面板)这里还要给树加上key,因为每个手风琴下面都是一个树 折叠面板饿了吗官网

2:树要展示前面的选择框,要给树组件加上show-checkbox属性。:default-checked-keys="selectMenus" 默认选中的key,这个selectMenus需要去data中定义一个数组。

3:在添加时,可通过 let tree = this.$refs.tree[index]; 拿到整个手风琴下面的树,let selectedKeys = tree.getCheckedKeys(true) 获取选中节点的id,修改成功后,把手风琴的折叠属性,定义成-1,折叠即可,因为下次再打开的时候,会去数据库查出这个角色对应菜单的最新数据。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/60997.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

给出32位有符号整数,将这个整数翻转

例1 收入123 输出321 例2 输入-123 输出-321 例3 输入120 输出21 答案 思路&#xff0c; 1、先考虑末尾是0的情况时&#xff0c;翻转后需要把0去掉&#xff0c; 2、当有-号时&#xff0c;把翻转后末尾的-号去掉&#xff0c;再在前面加一个-号 3、正数时不变 a -564…

轻松掌握线性代数-万字长文基础知识概览

轻松掌握线性代数-万字长文基础知识概览1 集合相关知识1.1 映射与像1.2 映射与像1.3 线性映射2 矩阵2.1 特殊矩阵2.1.1 零矩阵2.1.2 转置矩阵2.1.3 对称矩阵2.1.4 上三角矩阵2.1.5 下三角矩阵2.1.6 对角矩阵2.1.7 单位矩阵2.1.8 逆矩阵2.2 行列式2.2.1 根据行列式判断是否可逆2…

Java内存模型基础(JMM)

前言 在并发编程中&#xff0c;一般需要处理两个关键问题&#xff1a;线程通信、线程同步&#xff0c;然而线程通信一般的方式有&#xff1a;共享内存、消息传递。 对于共享内存的通信方式&#xff0c;线程同步是显示进行的&#xff0c;程序员必须指定某个方法或者某个代码段需…

并发基本原理(四):AQS源码解析1-ReentrantLock的lock实现原理

简介 AQS&#xff08;AbstractQueuedSynchronizer&#xff09;是JUC包中的核心抽象类&#xff0c;许多并发工具的实现&#xff0c;包括ReentrantLock、ReentrantReadWriteLock、CountDownLatch、Semaphore 等都是基于此实现。 AQS&#xff0c;主要提供了表示同步状态的 state…

Kafka - 主题Topic与消费者消息Offset日志记录机制

Kafka Topic 可以根据业务类型&#xff0c;分发到不同的Topic中&#xff0c;对于每一个Topic&#xff0c;下面可以有多个分区(Partition)日志文件: kafka 下的Topic的多个分区&#xff0c;每一个分区实质上就是一个队列&#xff0c;将接收到的消息暂时存储到队列中&#xff0…

CTFHub | 过滤空格

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

[附源码]Python计算机毕业设计SSM京东仓库管理系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

[附源码]计算机毕业设计项目管理系统的专家评审模块Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

项目管理逻辑:项目如何算是做完?什么是项目管理中的PPP模式?

目录 1.企业中的两件事 2.ppp模式---项目和运营的交织案例 1.企业中的两件事 一个是项目;一个是运营.项目是阶段性一次性的工作; 运营是持续性重复性的工作:职能部门,财务部, 采购部,人力部门,每个月都要报税, 每个月都要招聘, 每个月都要报销, 每天都要记账,. 注意,不确定性…

JMeter入门教程(14)——场景设计

1.JMeter中场景设计是通过线程组来实现的 如图&#xff1a; 控制面板中各元素介绍&#xff1a; 名称&#xff1a;可以随意设置&#xff0c;最好有业务意义。 注释&#xff1a;可以随意设置&#xff0c;可以为空。 在取样器错误后要执行的动作&#xff1a;其中的某一个请求出错后…

MySQL更新一条已经存在的sql语句是怎么执行的

MySQL更新一条已经存在的sql语句是怎么执行的1. 问题描述2. 分析验证1. 问题描述 今天看到一个有意思的问题&#xff0c;就是Mysql更新一条已经存在的语句是怎么执行的&#xff0c;结果显示&#xff0c;匹配(rows matched)了一行&#xff0c;修改(Changed)了0行。&#xff0c;…

sql集锦

sql集锦查询本月数据新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的Ka…

《MongoDB》Mongo Shell中的基本操作-更新操作一览

前端博主&#xff0c;热衷各种前端向的骚操作&#xff0c;经常想到哪就写到哪&#xff0c;如果有感兴趣的技术和前端效果可以留言&#xff5e;博主看到后会去代替大家踩坑的&#xff5e; 主页: oliver尹的主页 格言: 跌倒了爬起来就好&#xff5e; 来个关注吧&#xff0c;点个赞…

“剧情+综艺” 助推国潮文化破圈

一舞千年&#xff0c;重现大唐辉煌&#xff1b;一曲流光&#xff0c;雕琢岁月模样&#xff1b;一纸云烟&#xff0c;漫卷诗书山河&#xff1b;跨历史长河&#xff0c;览盛世华章。自从河南卫视开启“剧情综艺”的晚会形式&#xff0c;晚会便多了一种呈现方式。 从2021年《唐宫夜…

本周XR新闻:吴德周成立AR硬件公司,SideQuest支持PICO、Magic Leap

本周AR/VR大新闻&#xff0c;AR方面&#xff1a;吴德周成立AR硬件公司“致敬未知科技”&#xff1b;彭博称苹果AR操作系统或命名“xrOS”&#xff1b;AR眼镜开源方案OpenAR亮相&#xff1b;Epic 3D扫描工具RealityScan上线&#xff1b;Qoncept推出基于AI的实时姿态追踪系统。 …

Docker_实用篇_Docker-Compose_微服务部署

Docker_实用篇_Docker-Compose_微服务部署 文章目录Docker_实用篇_Docker-Compose_微服务部署4.1Docker-Compose4.2.初识DockerCompose4.3.部署微服务集群4.3.1.打包前文件汇总4.3.2.修改微服务配置4.3.3.打包4.3.4.拷贝jar包到部署目录4.3.5.部署4.1Docker-Compose Docker Co…

Vue(第十六课)JSON-SERVE和POSTMAN技术中对数据的增删改查

今天来聊聊axios技术 同样将官网地址放在博客里: 邮递员API平台|免费注册 (postman.com) json-server - npm (npmjs.com) 起步 | A jsxios 中文文档 | Axios 中文网 (axios-http.cn) 了解一下概念: 1 Axios Axios 是一个基于 promise 网络请求库&#xff0c;作用于node.js …

五、伊森商城 前端基础-Vue p24

目录 1、v-on 2、事件修饰符 3、按键修饰符 3.1、组合按钮 4、v-for 5、v-if和v-show 6、v-else 和 v-else-if 6.1、v-if结合v-for来时用 1、v-on v-on 指令用于给页面元素绑定事件。 语法&#xff1a; v-on:事件名"js 片段或函数名"事件绑定可以简写&#xff…

[附源码]计算机毕业设计基于JEE平台springboot技术的订餐系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Dcoker入门,小白也学得懂!

目录 一、Dcoker简介 二、Centos7安装Docker 三、Docker 容器运行原理解析 四、阿里云镜像仓库配置 一、Dcoker简介 1.1简单介绍 Docker 是一个开源的应用容器引擎&#xff0c;基于 Go 语言 并遵从Apache2.0协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个…