zoukankan      html  css  js  c++  java
  • ElementUI Tree 树形控件

    一、概述

    用清晰的层级结构展示信息,可展开或折叠。

    官方网站:https://element.eleme.cn/#/zh-CN/component/tree

    二、节点过滤

    通过关键字过滤树节点

    test.vue

    <template>
      <div style=" 20%">
        <el-input
          placeholder="输入关键字进行过滤"
          v-model="filterText">
        </el-input>
    
        <el-tree
          class="filter-tree"
          :data="data"
          :props="defaultProps"
          :default-expand-all="false"
          :filter-node-method="filterNode"
          @node-click="handleNodeClick"
          ref="tree">
        </el-tree>
      </div>
    </template>
    
    <script>
      export default {
        // 监听器
        watch: {
          filterText(val) {
            if (val) {
              this.$refs.tree.filter(val)
            }else {
              this.$refs.tree.filter(null)
            }
          }
        },
    
        methods: {
          // 过滤节点
          filterNode(value, data) {
            if (!value) return true;
            return data.label.indexOf(value) !== -1;
          },
          // 点击节点
          handleNodeClick(data){
            console.log("点击了",data)
          },
        },
    
        data() {
          return {
            filterText: '',
            data: [{
              id: 1,
              label: '北京',
              parentId:'',
              children: [{
                id: 4,
                label: '海淀',
                parentId:1,
                children: [{
                  id: 9,
                  label: '五道口',
                  parentId:4,
                }, {
                  id: 10,
                  label: '中关村',
                  parentId:4,
                }]
              }]
            }, {
              id: 2,
              label: '上海',
              parentId:'',
              children: [{
                id: 5,
                label: '闵行',
                parentId:2,
                children: [{
                  id: 11,
                  label: '人民广场',
                  parentId:5,
                }, {
                  id: 12,
                  label: '锦江乐园',
                  parentId:5,
                }]
              }, {
                id: 12,
                label: '闸北',
                parentId:2,
                children: [{
                  id: 13,
                  label: '河南北路',
                  parentId:12,
                }, {
                  id: 14,
                  label: '武进路',
                  parentId:12,
                }]
              }]
            }],
            defaultProps: {
              children: 'children',
              label: 'label'
            }
          };
        }
      }
    </script>
    
    <style scoped>
    
    </style>
    View Code

    效果如下:

     

    element ui 里面的tree 自带的搜索功能是默认搜索的全部数据,有关键字的显示,没有的不显示。

    如上图,其实闵行下面还有第三层,但是点击,无法展开。实际使用情况,是需要展开的。

    因此,搜索 tree 时,如果非叶子节点里面含有关键字,那么就显示此节点下的所有节点,此节点下的所有节点不参与过滤;

    解决办法,增加findSearKey方法,完整代码如下:

    test.vue

    <template>
      <div style=" 20%">
        <el-input
          placeholder="输入关键字进行过滤"
          v-model="filterText">
        </el-input>
    
        <el-tree
          class="filter-tree"
          :data="data"
          :props="defaultProps"
          :default-expand-all="false"
          :filter-node-method="filterNode"
          @node-click="handleNodeClick"
          ref="tree">
        </el-tree>
      </div>
    </template>
    
    <script>
      export default {
        // 监听器
        watch: {
          filterText(val) {
            if (val) {
              this.$refs.tree.filter(val)
            }else {
              this.$refs.tree.filter(null)
            }
          }
        },
    
        methods: {
          // 过滤节点
          filterNode(value, data, node) {
            if (!value) return true;
            return this.findSearKey(node, value);
          },
          //递归搜索父级是否包含关键字
          findSearKey(node, key) {
            // console.log("findSearKey",node, key)
            if (node.label.indexOf(key) !== -1) {
              return true;
            } else {
              if (node.parent.parent == null) {
                return false;
              } else {
                return this.findSearKey(node.parent, key);
              }
            }
          },
          // 点击节点
          handleNodeClick(data){
            // console.log("点击了",data)
            for (let node of this.data) {
              for (let val of node.children) {
                if (data.parentId == val.id) {
                  let text=''
                  text=node.label+'-'+val.label+'-'+data.label
                  console.log("选中的三层数据为",text)
                }
              }
            }
          },
        },
    
        data() {
          return {
            filterText: '',
            data: [{
              id: 1,
              label: '北京',
              parentId:'',
              children: [{
                id: 4,
                label: '海淀',
                parentId:1,
                children: [{
                  id: 9,
                  label: '五道口',
                  parentId:4,
                }, {
                  id: 10,
                  label: '中关村',
                  parentId:4,
                }]
              }]
            }, {
              id: 2,
              label: '上海',
              parentId:'',
              children: [{
                id: 5,
                label: '闵行',
                parentId:2,
                children: [{
                  id: 11,
                  label: '人民广场',
                  parentId:5,
                }, {
                  id: 12,
                  label: '锦江乐园',
                  parentId:5,
                }]
              }, {
                id: 12,
                label: '闸北',
                parentId:2,
                children: [{
                  id: 13,
                  label: '河南北路',
                  parentId:12,
                }, {
                  id: 14,
                  label: '武进路',
                  parentId:12,
                }]
              }]
            }],
            defaultProps: {
              children: 'children',
              label: 'label'
            }
          };
        }
      }
    </script>
    
    <style scoped>
    
    </style>
    View Code

    效果如下:

    即使匹配第二层菜单,也可以展示第三层菜单。

    注意一下,以下代码:

    defaultProps: {
      children: 'children',
      label: 'label'
    }

    这里是定义默认的参数字段,上文的数据字典,例如:

    {
      id: 4,
      label: '二级 1-1',
      children: [{}]
    }

    菜单名字用lable表示,子级用children表示。

    如果你的数据字典是这样的

    {
      code: 2,
      description: '一级 2',
      children: [{}]
    }

    那么defaultProps需要修改为:

    defaultProps: {
      children: 'children',
      label: 'description'
    }

    所以,defaultProps的参数配置,是根据字典结构来变化的。

    注意findSearKey方法,不需要做任何改动,即使数据字典各种变化,它也不需要改动。因为它是根据树形结构对象来做处理的。

    三、默认展开节点

    如果需要默认展开第一层节点,可以设置default-expanded-keys参数。

    注意:使用default-expanded-keys参数,必须指定node-key参数,用来指定key值。

    修改el-tree部分代码,如下:

    <el-tree
          class="filter-tree"
          node-key="id"
          :data="data"
          :props="defaultProps"
          :default-expanded-keys="[1,2]"
          :default-expand-all="false"
          :filter-node-method="filterNode"
          @node-click="handleNodeClick"
          ref="tree">
    </el-tree>

    这里的node-key,表示数据字典中的键值,default-expanded-keys后面列表中的数值,就是第一层菜单的key,可以写多个。

    效果如下:

    默认就会把第一层菜单展开。

    本文参考链接:https://blog.csdn.net/crabfrog/article/details/116658938

  • 相关阅读:
    非阻塞式NIO 小案例(模拟聊天室)
    网络通信小案例,服务端接收成功要给客户端一个反馈(阻塞式)
    阻塞式网络通信小案例:
    NIO的非阻塞式网络通信
    字符编码
    使用分散(Scatter)与聚集(Gather)来实现文件的复制
    使用通道之间的数据传输(效果,也是实现文件的复制)
    创建直接缓存区完成文件的复制
    C++预处理详解
    C++的学习资源
  • 原文地址:https://www.cnblogs.com/xiao987334176/p/15308362.html
Copyright © 2011-2022 走看看