Henry Henry
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)

Henry

小学生中的前端大佬
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)
  • JavaScript

  • TypeScript

  • Vue

  • ElementUI

    • 基于 ElementUI 封装的 TextEllipsis
    • 基于 ElementUI 封装的 Tree
    • 基于 ElementUI 封装的 Tree2
    • 基于 ElementUI 封装的 SelectTree
    • 基于 ElementUI 封装的 NumberInput
    • 基于 ElementUI 封装的基础 table 和 form
    • 基于 ElementUI 封装的 TreeTable
    • 基于 VuePress 搭建一个类似 ElementUI 的说明文档
    • el-tree 节点过滤加载对应子节点
      • 假如有三级
      • 优化之后的代码 不管有几级都可以适用
        • 方法一
        • 方法二
        • 方法三
      • 区分大小写
      • 参考资料
    • 简单调试 node_modules 源码
    • ElementUI 问题集合
    • 树形表格更新后保持折叠状态
    • 开始和完成时间互相限制
  • React

  • AntD

  • 前端
  • ElementUI
Henry
2020-01-12
目录

el-tree 节点过滤加载对应子节点

el-tree 的官网例子, 不会返回过滤节点的子节点, 这也是总结这篇博客的原因.

在官网节点过滤 (opens new window)中输入 一 , 可以看到过滤后只有三个根节点了, 下面的所有子节点都没有显示出来

未显示子节点

  • 此时可以实现: 当点击搜索时, 只会搜索到当前节点包含该搜索字段 filterText 的树渲染
  • 而我们一般实际业务中, 需要搜索到其下所有的子节点
  • 实现方法如下(修改 filterNode 方法即可, 注意: filterNode 方法有三个参数)

实现思路一般就是返回当前节点或其父节点是否包含 filterText

显示子节点

# 假如有三级

filterNode(value, data, node) {
  if (!value) return true
  let if_one = node.label.indexOf(value) !== -1
  let if_two = node.parent && node.parent.label && node.parent.label.indexOf(value) !== -1
  let if_three =
    node.parent &&
    node.parent.parent &&
    node.parent.parent.label &&
    node.parent.parent.label.indexOf(value) !== -1
  let result_one = false
  let result_two = false
  let result_three = false
  if (node.level === 1) {
    result_one = if_one
  } else if (node.level === 2) {
    result_two = if_one || if_two
  } else if (node.level === 3) {
    result_three = if_one || if_two || if_three
  }
  return result_one || result_two || result_three
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 优化之后的代码 不管有几级都可以适用

# 方法一

filterNode(value, data, node) {
  if (!value) {
    return true
  }
  let _array = [] //这里使用数组存储 只是为了存储值。
  this.getReturnNode(node, _array, value)
  let result = false
  _array.forEach(item => {
    result = result || item
  })
  return result
}

getReturnNode(node, _array, value) {
  let isPass = node.label && node.label.indexOf(value) !== -1
  isPass ? _array.push(isPass) : ''
  if (!isPass && node.level !== 1 && node.parent) {
    this.getReturnNode(node.parent, _array, value)
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 方法二

filterNode(value, data, node) {
  // 如果什么都没填就直接返回
  if (!value) return true

  // 如果传入的value和data中的label相同说明是匹配到了
  if (node.label.indexOf(value) !== -1) {
    return true
  }
  // 否则要去判断它是不是选中节点的子节点
  return this.checkBelongToChooseNode(value, data, node)
}

// 判断传入的节点是不是选中节点的子节点
checkBelongToChooseNode(value, data, node) {
  const level = node.level
  // 如果传入的节点本身就是一级节点就不用校验了
  if (level === 1) {
    return false
  }
  // 先取当前节点的父节点
  let parentData = node.parent
  // 遍历当前节点的父节点
  let index = 0
  while (index < level - 1) {
    // 如果匹配到直接返回
    if (parentData.label.indexOf(value) !== -1) {
      return true
    }
    // 否则的话再往上一层做匹配
    parentData = parentData.parent
    index++
  }
  // 没匹配到返回false
  return false
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 方法三

这个更容易理解点, 将当前节点所在节点分支的名称连起来.

那么只要关键字在这个数组中出现过, 那整条分支上的节点全部显示.

filterNode(value, data, node) {
  if (!value) return true

  let parentNode = node.parent,
    labels = [node.label],
    level = 1

  while (level < node.level) {
    labels = [...labels, parentNode.label]
    parentNode = parentNode.parent
    level++
  }

  return labels.some(label => label.indexOf(value) !== -1)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 区分大小写

可以使用正则匹配:

return new RegExp(value, 'i').test(node.label)
1

也可以统一转化一下:

node.label.toLowerCase().indexOf(value.toLowerCase()) !== -1
1

# 参考资料

  • elementui tree 节点过滤加载对应子节点 - 简书 (opens new window)
编辑 (opens new window)
#Js#ElementUI
上次更新: 5/27/2023, 1:02:05 PM
基于 VuePress 搭建一个类似 ElementUI 的说明文档
简单调试 node_modules 源码

← 基于 VuePress 搭建一个类似 ElementUI 的说明文档 简单调试 node_modules 源码→

最近更新
01
version 1.15
07-01
02
version 1.14
06-27
03
version 1.13
06-27
更多文章>
Theme by Vdoing | Copyright © 2017-2023 HenryTSZ | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式