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: [],

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

相关推荐
牛蛙点点申请出战28 分钟前
IconFontViewer -- 一个可以在 Android Studio 中实时预览 IconFont 的插件
android·前端·intellij idea
空中海29 分钟前
03 渲染机制、性能优化与现代 React
javascript·react.js·性能优化
ChalesXavier1 小时前
Fetch API 的基本用法
javascript
是上好佳佳佳呀1 小时前
【前端(十三)】JavaScript 数组与字符串笔记
前端·javascript·笔记
巴沟旮旯儿1 小时前
vite项目配置文件和打包
前端·设计模式
彩票管理中心秘书长1 小时前
Pinia 插件架构与组合式函数:如何让你的 Store 长出“超能力”
前端
彩票管理中心秘书长1 小时前
Pinia 比 Vuex 强在哪?我用同一个模块写了两种实现,你自己看
前端
yingyima1 小时前
用 Cron 加 Webhook 打通自动化工作的任督二脉
前端
JackieDYH1 小时前
CSS Flexbox 与 Grid 的默认行为-布局的底层机制
前端·css·html