elementui-树形控件实现 两棵树的联动,两棵树有相同的id节点时节点的状态保持一致

1、遇到一个情景:需要勾选用户的权限和回显用户的权限,权限分为两棵树形结构,这两颗树有一些节点的id是一样的,需要在第一个树勾选的时候,另外一棵树也勾选,不勾选的时候状态保持一致,回显也是一样的操作

2、代码

树形的代码:

 <div
                          v-loading="IndexLoding"
                          style="
                            height: 29.5vh;
                            overflow-y: scroll;
                            border: 1px solid #ccc;
                            padding-left: 3px;
                            margin-bottom: 5px;
                          "
                        >
                          <el-tree
                            :data="deptOptionsOne"
                            show-checkbox
                            default-expand-all
                            ref="target_tree_one"
                            node-key="id"
                            :default-checked-keys="[resourceCheckedKey]"
                            :filter-node-method="filterNode"
                            :check-strictly="!form.deptCheckStrictly"
                            empty-text="暂无数据"
                            :props="defaultProps"
                            @check="handleCheckChange"
                          >
                            <template v-slot="{ node, data }">
                              <span
                                :class="{
                                  'disabled-node': data.status === null
                                }"
                                >{{ node.label }}</span
                              >
                            </template>
                          </el-tree>
                        </div>
                        <div
                          v-loading="IndexLoding"
                          style="
                            height: 29.5vh;
                            overflow-y: scroll;
                            border: 1px solid #ccc;
                            padding-left: 3px;
                            margin-bottom: 5px;
                          "
                        >
                          <el-tree
                            :data="deptOptionsTow"
                            show-checkbox
                            :default-checked-keys="[resourceCheckedKey]"
                            default-expand-all
                            ref="target_tree_Tow"
                            node-key="id"
                            :filter-node-method="filterNode"
                            :check-strictly="!form.deptCheckStrictly"
                            empty-text="暂无数据"
                            :props="defaultProps"
                            @check="handleCheckChangeTow"
                          >
                            <template v-slot="{ node, data }">
                              <span
                                :class="{
                                  'disabled-node': data.status === null
                                }"
                                >{{ node.label }}</span
                              >
                            </template>
                          </el-tree>
                        </div>

树形节点点击的事件

   // 用户权限-指标权限的第一棵树形控件方法
    // // 树形控件复选框的选中方法,每次选中对应的其他模块中相同id的复选框勾选上
    handleCheckChange(data, checkData) {
      // 这里的temp_data是个全局的变量,根据判断之前两棵树是否有选中来选择下面的走向
      // this.$refs.target_tree_Tow.setCheckedKeys(checkData.checkedKeys);
      if (!this.temp_data.length) {
        this.temp_data = checkData.checkedKeys;
        this.$refs.target_tree_Tow.setCheckedKeys(this.temp_data);
        // 第一次选中的话赋值给data_tree_first,这个算是旧值就是这次选中之前的选中的数据列表
        this.data_tree_first = this.$refs.target_tree_one.getCheckedKeys();
      } else {
        // 存储变化量id的数组
        let other_more = [];
        // 判断是否点击了全选的按钮,点了全选的话,选中的数量变化会大于1
        if (
          this.data_tree_first.length -
            this.$refs.target_tree_one.getCheckedKeys().length >
          1
        ) {
          this.data_tree_first.forEach((element) => {
            if (
              this.$refs.target_tree_one.getCheckedKeys().indexOf(element) == -1
            ) {
              // 之前有的节点和现在的节点进行对比,没有的就是那个变化的量,也就是新加的节点的id
              other_more.push(element);
            }
          });
        }
        // 把这次选中的节点保存下来,就是下一次遍历的旧值了
        this.data_tree_first = this.$refs.target_tree_one.getCheckedKeys();
        // 对第二个树的操作--开始
        let tow_tree_data = [];
        // 拿取第二棵树现在获取的节点,---!!这里有一个注意点,拿取的是勾选的子节点id不是所有勾选的id
        for (
          let index = 0;
          index < this.$refs.target_tree_Tow.getCheckedNodes(true).length;
          index++
        ) {
          tow_tree_data.push(
            this.$refs.target_tree_Tow.getCheckedNodes(true)[index].id
          );
        }
        // console.log('第二棵树选中的数据', tow_tree_data);
        // 针对只勾选一个节点的处理方法
        let index = tow_tree_data.indexOf(data.id);
        // 如果此次点击的节点id存在在第二课树里面就把这个id从第二棵树的选中节点数组中删除
        if (index !== -1) {
          tow_tree_data.splice(index, 1);
        }
        // 选择了全选这种比较大的按钮,变化量比较多的数组,通过遍历把之前第二棵树在这个变化量里面有的数据抹去
        other_more.forEach((element) => {
          let index = tow_tree_data.indexOf(element);
          if (index !== -1) {
            tow_tree_data.splice(index, 1);
          }
        });
        // 最后把第一棵树选中的id直接一股脑的push给第二棵树将来的勾的数据
        checkData.checkedKeys.forEach((element) => {
          tow_tree_data.push(element);
        });

        console.log('@222', tow_tree_data);
        // 通过绑定id直接渲染
        this.$refs.target_tree_Tow.setCheckedKeys(tow_tree_data);
      }
    },
    // 用户权限-指标权限的第二棵树形控件方法
    handleCheckChangeTow(data, checkData) {
      if (!this.temp_data.length) {
        this.temp_data = checkData.checkedKeys;
        this.$refs.target_tree_one.setCheckedKeys(this.temp_data);
        this.data_tree_second = this.$refs.target_tree_Tow.getCheckedKeys();
      } else {
        if (!this.data_tree_second.length) {
          this.data_tree_second = this.$refs.target_tree_Tow.getCheckedKeys();
        }
        let other_more = [];
        // 判断是否点击了全选的按钮
        if (
          this.data_tree_second.length -
            this.$refs.target_tree_Tow.getCheckedKeys().length >
          1
        ) {
          // console.log('超过一个了');
          this.data_tree_second.forEach((element) => {
            if (
              this.$refs.target_tree_Tow.getCheckedKeys().indexOf(element) == -1
            ) {
              other_more.push(element);
              // console.log('对比之后的数据', other_more);
            }
          });
        }
        this.data_tree_second = this.$refs.target_tree_Tow.getCheckedKeys();

        let one_tree_data = [];

        // console.log(
        //   '第一棵树选中的信息',
        //   this.$refs.target_tree_one.getCheckedNodes(true),
        //   this.$refs.target_tree_one.getCheckedNodes(true).length
        // );
        for (
          let index = 0;
          index < this.$refs.target_tree_one.getCheckedNodes(true).length;
          index++
        ) {
          // const element = array[index];
          one_tree_data.push(
            this.$refs.target_tree_one.getCheckedNodes(true)[index].id
          );
        }
        let index = one_tree_data.indexOf(data.id);
        if (index !== -1) {
          one_tree_data.splice(index, 1);
        }
        other_more.forEach((element) => {
          let index = one_tree_data.indexOf(element);
          if (index !== -1) {
            one_tree_data.splice(index, 1);
          }
        });
        checkData.checkedKeys.forEach((element) => {
          one_tree_data.push(element);
        });
        one_tree_data = this.unique(one_tree_data);
        // console.log('@@!!', one_tree_data);
        // this.resourceCheckedKey = [];
        // this.$refs.target_tree_one.setCheckedKeys([]);
        this.$refs.target_tree_one.setCheckedKeys(one_tree_data);
        // console.log('$$$', this.$refs.target_tree_one.getCheckedKeys());
      }
    },

  // 筛选节点
    filterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },

data数据

 defaultProps: {
        children: 'children',
        label: 'label'
        // disabled: function (data, node) {
        //   if (data.status === null) {
        //     return 1;
        //   }
        // }
      },
 resourceCheckedKey: [],

注:提供一个思路 很多变量都是不需要的 重点在于两棵树的节点点击事件代码

相关推荐
Martin -Tang2 分钟前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发3 分钟前
解锁微前端的优秀库
前端
王解1 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
老码沉思录1 小时前
写给初学者的React Native 全栈开发实战班
javascript·react native·react.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
放逐者-保持本心,方可放逐2 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
毋若成4 小时前
前端三大组件之CSS,三大选择器,游戏网页仿写
前端·css
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新5 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html