首先官网上的树形控件教程地址为Element - The world's most popular Vue UI framework
要实现这种类型的树控件,并且后边相关操作:

首先,数据库表为:

查询接口返回的实体类为:
- @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
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
- }
- ]
从官网上复制一个模板过来,搜索的话,直接往下找一个有搜索框的,把搜索框复制过来,复制好就可以开始修改,写增删改查的方法调用了。

写好的代码如下:
- <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">
-
- <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
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
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的状态,之后还是一样,在一层中没有查询到的话,就递归到下一层去找。
这种前面带有选择框的,进行授权操作

对应的数据库表

对应的实体类:
- @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
-
- @ApiModelProperty(value = "角色列表")
- @TableField(exist = false)
- private List
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
- }
- ]
- }
- <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,折叠即可,因为下次再打开的时候,会去数据库查出这个角色对应菜单的最新数据。