element中Tree 树形控件实现节点过滤和懒加载节点

1.代码实现

<template>
  <div class="TreePage">
    <el-row :gutter="20">
      <!--村数据-->
      <el-col :span="24">
        <div class="head-container">
          <el-input v-model="deptName" placeholder="请输入名称" clearable size="small" prefix-icon="el-icon-search"
            style="margin-bottom: 20px" />
        </div>
        <!-- 组织树 -->
        <div class="head-container">
          <el-tree ref="tree" :props="defaultProps" :default-expanded-keys="treeData" :expand-on-click-node="false"
            :load="loadNode" lazy node-key="deptId" :filter-node-method="filterNode" @node-click="handleNodeClick" />
        </div>
      </el-col>
    </el-row>
  </div>
</template>
      
<script>
// import { lazyList } from '@/api/manager/tree'
export default {
  name: "TreePage",
  props: {},
  data() {
    return {
      // 模拟数据
      analoDdata_01: [
        {
          "deptId": 100,
          "parentId": 0,
          "parentName": null,
          "ancestors": "0",
          "deptName": "XX街道",
          "children": [],
          "existSub": true, //是否还存在下级
        }
      ],
      analoDdata_02: [
        {
          "deptId": 1201,
          "parentId": 100,
          "parentName": null,
          "ancestors": "0,100",
          "deptName": "XX01村",
          "children": [],
          "existSub": true
        },
        {
          "deptId": 1202,
          "parentId": 100,
          "parentName": null,
          "ancestors": "0,100",
          "deptName": "XX02村",
          "children": [],
          "existSub": true
        },
        {
          "deptId": 1203,
          "parentId": 100,
          "parentName": null,
          "ancestors": "0,100",
          "deptName": "XX03村",
          "children": [],
          "existSub": false
        }

      ],
      // 村名称
      deptName: undefined,
      defaultProps: {
        children: 'children',
        label: 'deptName',
        isLeaf: 'leaf',//指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效
      },
      // 默认展开的节点的 key 的数组
      treeData: [],
    };
  },
  watch: {
    // 在需要对节点进行过滤时,调用 Tree 实例的filter方法,参数为关键字。
    // 需要注意的是,此时需要设置filter-node-method,值为过滤函数。
    // 根据名称筛选村社树
    deptName(val) {
      this.$refs.tree.filter(val)
    }
  },
  methods: {
    //  关于树懒加载 (组件加载完成后,会主动触发一次),后续则是点击时候会触发,
    // 或者通过default-expanded-keys默认展开的节点的 key 的数组来触发这个方法,实现指定加载哪几层的数据。
    loadNode(node, resolve) {
      console.log(node, 'node')
      // 如果展开第一级节点,从后台加载一级节点列表
      if (node.level == 0) { // 获取第一层 也就是 analoDdata_01的数据
        console.log('第一级节点')
        const queryParams = {}
        this.loadNodeHandle(resolve, queryParams, 1) //1获取模拟数据需要,实际可不用传递
      }
      // 如果展开其他级节点,动态从后台加载下一级节点列表
      if (node.level >= 1) { // 获取第一层的下级 也就是 analoDdata_02的数据
        console.log('其他级节点')
        const queryParams = {}
        // 根据当前节点的id,查询他下级的相关节点
        queryParams.parentId = node.key
        this.loadNodeHandle(resolve, queryParams, 2)// 2获取模拟数据需要,实际可不用传递
      }
    },
    async loadNodeHandle(resolve, queryParams, type) {
      console.log(queryParams, 'queryParams')
      // 根据实践项目调用接口
      // const list = await lazyList(queryParams).then(res => {
      //   console.log(res, '关于树懒加载')
      //   res.data.forEach(item => {
      //     item.leaf = !item.existSub
      //   })
      //   return res.data
      // })

      // 模拟数据
      let list = [];
      if (type == 1) {
        list = this.analoDdata_01
        list.forEach(item => {
          item.leaf = !item.existSub
        })
      } else if (type == 2) {
        list = this.analoDdata_02
        list.forEach(item => {
          item.leaf = !item.existSub
        })
      }
      
      // 根据某些条件,获取到需要默认展开的节点的 key 的数组 this.treeData; 
      // this.treeData 中的id对应的节点,都会默认加载loadNode方法获取其下级数据,并展开;
      if (list.length == 1) {
        list.forEach(element => {
          this.treeData.push(element.deptId)
        })
      }

      return resolve(list)
    },
    // 过滤函数
    filterNode(value, data) {
      // console.log(value, data)
      if (!value) return true
      return data.deptName.indexOf(value) !== -1
    },
    // 左侧网格树-节点单击事件
    handleNodeClick(data) {
      console.log(data, '左侧网格树-节点单击事件')
    },
  },

};
</script>
      

2. 效果图

在这里插入图片描述

3. 使用到的部分属性说明

  1. default-expanded-keys: 默认展开的节点的 key 的数组;
  2. expand-on-click-node: 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点;
  3. load :加载子树数据的方法,仅当 lazy 属性为true 时生效;
  4. lazy :是否懒加载子节点,需与 load 方法结合使用;
  5. node-key :每个树节点用来作为唯一标识的属性,整棵树应该是唯一的;
  6. filter-node-method: 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏;
  7. node-click :节点被点击时的回调;

4. 更多属性配置查看element官网

https://element.eleme.cn/#/zh-CN/component/tree

  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Element UITree 树形控件,可以结合使用过滤和 show-checkbox 属性来实现节点过滤和只能选择可见节点的效果。具体实现步骤如下: 1. 设置 Tree 组件的 filter-node-method 属性,这个属性可以指定一个过滤方法,用于过滤不需要显示的节点。例如: ```html <template> <el-tree :data="data" :filter-node-method="filterNode" :show-checkbox="true" @check-change="handleCheckChange" ></el-tree> </template> <script> export default { data() { return { data: [ // 树形数据 ] } }, methods: { filterNode(value, data) { // 过滤节点的方法 // value 为搜索框输入的值 // data 为当前节点的数据对象 // 返回 true 表示需要显示节点,返回 false 表示不需要显示节点 return data.label.indexOf(value) !== -1; }, handleCheckChange(data, checked) { // 处理节点事件 // data 为选节点的数据对象 // checked 为选状态,true 为选,false 为取消选 } } } </script> ``` 上面的代码,我们设置了 filter-node-method 属性为 filterNode 方法。这个方法会在过滤节点时被调用,我们在这个方法通过判断当前节点的 label 是否包含搜索框输入的值来决定节点是否需要显示。 2. 在 handleCheckChange 方法,需要判断当前选节点是否可见。如果节点不可见,则需要取消选它。例如: ```javascript handleCheckChange(data, checked) { const node = this.$refs.tree.getNode(data.key); // 获取当前节点的 DOM 元素 if (node && !node.offsetParent) { // 如果节点不可见,则取消选它 this.$refs.tree.setChecked(data.key, false); } } ``` 上面的代码,我们首先通过 this.$refs.tree.getNode(data.key) 方法获取当前节点的 DOM 元素,然后判断这个元素的 offsetParent 属性是否为 null。如果为 null,说明节点不可见,我们就通过 this.$refs.tree.setChecked(data.key, false) 方法取消选它。 通过上面的实现,我们就可以实现节点过滤和只能选择可见节点的效果了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值