最近在使用ruoyi时发现有对el-tree有3个协助功能使用。

el-tree树的全部展开(折叠),全选(全不选),父子联动_全不选



1、准备代码

首先准备 el-tree 组件与三个复选框,做好三个复选框的双向绑定和 change 事件

  • node-key: 每个树节点用来作为唯一标识的属性,不能不写;
  • props:label 指定节点标签为节点对象的某个属性值;
  • children 指定子树为节点对象的某个属性值;
  • show-checkbox: 节点是否可被选择,写了组件会在每个节点前面显示一个复选框供用户选择节点,后续要展开/全选/父子联动,都需要设置 show-checkbox 的值为 true ,不能不写 ;
  • data:组件关联的数据,不能不写;
  • ref: 后续要使用treeRef来获取el-tree 元素,不能不写;
<el-tree
            ref="treeRef"
            style="max-width: 600px"
            :data="data"
            show-checkbox
            default-expand-all
            node-key="menuId"
            highlight-current
            :check-strictly="!menuCheckStrictly"
            :props="defaultProps"
          />

test001.vue

<template>
    <div>
        <div><h1>test001/test001</h1></div>
        <span>这个是测试内容哦</span>
        <hr></hr>
        <el-checkbox v-model="menuExpand" @change="handleCheckedTreeExpand">展开/折叠</el-checkbox>
        <el-checkbox v-model="menuNodeAll" @change="handleCheckedTreeNodeAll" >全选/全不选</el-checkbox>
        <el-checkbox v-model="menuCheckStrictly">父子联动</el-checkbox>
        <hr></hr>
          <el-tree
            ref="treeRef"
            style="max-width: 600px"
            :data="data"
            show-checkbox
            default-expand-all
            node-key="menuId"
            highlight-current
            :check-strictly="!menuCheckStrictly"
            :props="defaultProps"
          />
        
          <div class="buttons">
            <el-button @click="getCheckedNodes">get by node</el-button>
            <el-button @click="getCheckedKeys">get by key</el-button>
            <el-button @click="setCheckedNodes">set by node</el-button>
            <el-button @click="setCheckedKeys">set by key</el-button>
            <el-button @click="resetChecked">reset</el-button>
            <el-button @click="abcCheckAll">abcCheckAll</el-button>
            <el-button @click="abcdCheckAll">abcdCheckAll</el-button>
            
          </div>
    </div>
</template>

<script setup>
import { axiosInstance } from '@/utils/srequest.js';
import { ref, reactive, onMounted, onUnmounted } from 'vue';

let treeRef = ref();
let data = ref([]);
let defaultArray = ref([]);

let defaultProps = {
  children: 'children',
  label: 'menuName',
};
let menuExpand = ref(false);
let menuNodeAll = ref(false);
let menuCheckStrictly = ref(false);

let getCheckedNodes = () => {
  console.log(treeRef.value.getCheckedNodes(false, false))
}
let getCheckedKeys = () => {
  console.log(treeRef.value.getCheckedKeys(false))
}
let setCheckedNodes = () => {
  treeRef.value.setCheckedNodes(
    [
      {
        menuId: 9995,
        menuName: 'Level two 2-1',
      },
      {
        menuId: 9996,
        menuName: 'Level three 1-1-1',
      },
    ],
    false
  )
}
let setCheckedKeys = () => {
  treeRef.value.setCheckedKeys([3], false)
}
let resetChecked = () => {
  treeRef.value.setCheckedKeys([], false)
}

let abcCheckAll = () => {
  axiosInstance.get('/test001/test005').then(res => {
    console.log(res);
    defaultArray.value = res;
    console.log("-------------------------------------------");
    console.log(defaultArray.value);
    treeRef.value.setCheckedKeys(defaultArray.value, false);
  });
}


let abcdCheckAll = () => {
  console.log(treeRef.value.getHalfCheckedKeys(false));
}


let handleCheckedTreeExpand = (e) => {
    console.log(e);
    for (let i = 0; i < treeRef.value.store._getAllNodes().length; i++) {
      treeRef.value.store._getAllNodes()[i].expanded = e;
    }
}
let handleCheckedTreeNodeAll = (e) => {
  console.log(e);
  //treeRef.value.setCheckedNodes(e ? data.value : []);
  let temp = treeRef.value.store._getAllNodes();
  console.log(temp.length);
  console.log(temp);
  temp.map(item => {
    item.checked = e;
  });
}
let handleCheckedTreeConnect = (e) => {
   menuCheckStrictly = e ? true : false;
}





onMounted(() => {
  axiosInstance.get("/test001/test004").then(res => {
    console.log(res);
    data.value = res;

    console.log("-------------------------------------------");
    console.log(data.value);
  });


});
</script>

<script>
export default {
  name: 'Test001'
}
</script>

<style scope lang="scss">

</style>




2、展开/折叠

解析:

  • treeRef获取 el-tree 元素;
  • treeRef.store._getAllNodes() 的作用是获取 el-tree 组件的全部节点,store 中包含el-tree 组件的 getCheckedKeys 、setCheckedKeys、_getAllNodes 等全部方法,这一点在官方文档上并未体现,但 element 源码中将方法挂载到 el-tree 的 store 中了,详见源码中 packages\tree\src\model\tree-store.js 文件;
  • expanded 是 el-tree 节点 的属性,表示是否展开(true为展开);
let handleCheckedTreeExpand = (e) => {
    console.log(e);
    for (let i = 0; i < treeRef.value.store._getAllNodes().length; i++) {
      treeRef.value.store._getAllNodes()[i].expanded = e;
    }
}



3、全选/全不选

解析:

  • 全选就将存储全部节点的数组 data作为参数传入 setCheckedNodes 方法,setCheckedNodes 可以设置目前勾选的节点,使用此方法必须设置 node-key 属性
  • 全不选就将空数组作为参数传入
let handleCheckedTreeNodeAll = (e) => {
  console.log(e);
  //treeRef.value.setCheckedNodes(e ? data.value : []);
  let temp = treeRef.value.store._getAllNodes();
  console.log(temp.length);
  console.log(temp);
  temp.map(item => {
    item.checked = e;
  });
}



4、父子联动

解析:

  • check-strictly 表示是否遵循父子不互相关联的做法,true 为遵循,false 为不遵循,默认值为false;
  • 当联动按钮状态为 true 时,表示想要将 el-tree 组件设置为 不遵循父子不互相关联,也就是设置 check-strictly 的值为 false ,因此联动按钮绑定 v-model = "form.menuCheckStrictly",el-tree 组件绑定 :check-strictly="!form.menuCheckStrictly"
let handleCheckedTreeConnect = (e) => {
   menuCheckStrictly = e ? true : false;
}