Tree 树形控件

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

基础用法

基础的树形结构展示。

 1 <el-tree :data="data" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
 2 
 3 <script>
 4   export default {
 5     data() {
 6       return {
 7         data: [{
 8           label: '一级 1',
 9           children: [{
10             label: '二级 1-1',
11             children: [{
12               label: '三级 1-1-1'
13             }]
14           }]
15         }, {
16           label: '一级 2',
17           children: [{
18             label: '二级 2-1',
19             children: [{
20               label: '三级 2-1-1'
21             }]
22           }, {
23             label: '二级 2-2',
24             children: [{
25               label: '三级 2-2-1'
26             }]
27           }]
28         }, {
29           label: '一级 3',
30           children: [{
31             label: '二级 3-1',
32             children: [{
33               label: '三级 3-1-1'
34             }]
35           }, {
36             label: '二级 3-2',
37             children: [{
38               label: '三级 3-2-1'
39             }]
40           }]
41         }],
42         defaultProps: {
43           children: 'children',
44           label: 'label'
45         }
46       };
47     },
48     methods: {
49       handleNodeClick(data) {
50         console.log(data);
51       }
52     }
53   };
54 </script>
View Code

 

可选择

适用于需要选择层级时使用。

本例还展示了动态加载节点数据的方法。

 1 <el-tree
 2   :props="props"
 3   :load="loadNode"
 4   lazy
 5   show-checkbox
 6   @check-change="handleCheckChange">
 7 </el-tree>
 8 
 9 <script>
10   export default {
11     data() {
12       return {
13         props: {
14           label: 'name',
15           children: 'zones'
16         },
17         count: 1
18       };
19     },
20     methods: {
21       handleCheckChange(data, checked, indeterminate) {
22         console.log(data, checked, indeterminate);
23       },
24       handleNodeClick(data) {
25         console.log(data);
26       },
27       loadNode(node, resolve) {
28         if (node.level === 0) {
29           return resolve([{ name: 'region1' }, { name: 'region2' }]);
30         }
31         if (node.level > 3) return resolve([]);
32 
33         var hasChild;
34         if (node.data.name === 'region1') {
35           hasChild = true;
36         } else if (node.data.name === 'region2') {
37           hasChild = false;
38         } else {
39           hasChild = Math.random() > 0.5;
40         }
41 
42         setTimeout(() => {
43           var data;
44           if (hasChild) {
45             data = [{
46               name: 'zone' + this.count++
47             }, {
48               name: 'zone' + this.count++
49             }];
50           } else {
51             data = [];
52           }
53 
54           resolve(data);
55         }, 500);
56       }
57     }
58   };
59 </script>
View Code

 

懒加载自定义叶子节点

由于在点击节点时才进行该层数据的获取,默认情况下 Tree 无法预知某个节点是否为叶子节点,所以会为每个节点添加一个下拉按钮,如果节点没有下层数据,则点击后下拉按钮会消失。同时,你也可以提前告知 Tree 某个节点是否为叶子节点,从而避免在叶子节点前渲染下拉按钮。

 1 <el-tree
 2   :props="props1"
 3   :load="loadNode1"
 4   lazy
 5   show-checkbox>
 6 </el-tree>
 7 
 8 <script>
 9   export default {
10     data() {
11       return {
12         props1: {
13           label: 'name',
14           children: 'zones',
15           isLeaf: 'leaf'
16         },
17       };
18     },
19     methods: {
20       loadNode1(node, resolve) {
21         if (node.level === 0) {
22           return resolve([{ name: 'region' }]);
23         }
24         if (node.level > 1) return resolve([]);
25 
26         setTimeout(() => {
27           const data = [{
28             name: 'leaf',
29             leaf: true
30           }, {
31             name: 'zone'
32           }];
33 
34           resolve(data);
35         }, 500);
36       }
37     }
38   };
39 </script>
View Code

 

默认展开和默认选中

可将 Tree 的某些节点设置为默认展开或默认选中

分别通过default-expanded-keys和default-checked-keys设置默认展开和默认选中的节点。需要注意的是,此时必须设置node-key,其值为节点数据中的一个字段名,该字段在整棵树中是唯一的。

 1 <el-tree
 2   :data="data2"
 3   show-checkbox
 4   node-key="id"
 5   :default-expanded-keys="[2, 3]"
 6   :default-checked-keys="[5]"
 7   :props="defaultProps">
 8 </el-tree>
 9 
10 <script>
11   export default {
12     data() {
13       return {
14         data2: [{
15           id: 1,
16           label: '一级 1',
17           children: [{
18             id: 4,
19             label: '二级 1-1',
20             children: [{
21               id: 9,
22               label: '三级 1-1-1'
23             }, {
24               id: 10,
25               label: '三级 1-1-2'
26             }]
27           }]
28         }, {
29           id: 2,
30           label: '一级 2',
31           children: [{
32             id: 5,
33             label: '二级 2-1'
34           }, {
35             id: 6,
36             label: '二级 2-2'
37           }]
38         }, {
39           id: 3,
40           label: '一级 3',
41           children: [{
42             id: 7,
43             label: '二级 3-1'
44           }, {
45             id: 8,
46             label: '二级 3-2'
47           }]
48         }],
49         defaultProps: {
50           children: 'children',
51           label: 'label'
52         }
53       };
54     }
55   };
56 </script>
View Code

 

禁用状态

可将 Tree 的某些节点设置为禁用状态

通过disabled设置禁用状态。

 1 <el-tree
 2   :data="data3"
 3   show-checkbox
 4   node-key="id"
 5   :default-expanded-keys="[2, 3]"
 6   :default-checked-keys="[5]">
 7 </el-tree>
 8 
 9 <script>
10   export default {
11     data() {
12       return {
13         data3: [{
14           id: 1,
15           label: '一级 2',
16           children: [{
17             id: 3,
18             label: '二级 2-1',
19             children: [{
20               id: 4,
21               label: '三级 3-1-1'
22             }, {
23               id: 5,
24               label: '三级 3-1-2',
25               disabled: true
26             }]
27           }, {
28             id: 2,
29             label: '二级 2-2',
30             disabled: true,
31             children: [{
32               id: 6,
33               label: '三级 3-2-1'
34             }, {
35               id: 7,
36               label: '三级 3-2-2',
37               disabled: true
38             }]
39           }]
40         }],
41         defaultProps: {
42           children: 'children',
43           label: 'label'
44         }
45       };
46     }
47   };
48 </script>
View Code

 

树节点的选择

本例展示如何获取和设置选中节点。获取和设置各有两种方式:通过 node 或通过 key。如果需要通过 key 来获取或设置,则必须设置node-key。

 1 <el-tree
 2   :data="data2"
 3   show-checkbox
 4   default-expand-all
 5   node-key="id"
 6   ref="tree"
 7   highlight-current
 8   :props="defaultProps">
 9 </el-tree>
10 
11 <div class="buttons">
12   <el-button @click="getCheckedNodes">通过 node 获取</el-button>
13   <el-button @click="getCheckedKeys">通过 key 获取</el-button>
14   <el-button @click="setCheckedNodes">通过 node 设置</el-button>
15   <el-button @click="setCheckedKeys">通过 key 设置</el-button>
16   <el-button @click="resetChecked">清空</el-button>
17 </div>
18 
19 <script>
20   export default {
21     methods: {
22       getCheckedNodes() {
23         console.log(this.$refs.tree.getCheckedNodes());
24       },
25       getCheckedKeys() {
26         console.log(this.$refs.tree.getCheckedKeys());
27       },
28       setCheckedNodes() {
29         this.$refs.tree.setCheckedNodes([{
30           id: 5,
31           label: '二级 2-1'
32         }, {
33           id: 9,
34           label: '三级 1-1-1'
35         }]);
36       },
37       setCheckedKeys() {
38         this.$refs.tree.setCheckedKeys([3]);
39       },
40       resetChecked() {
41         this.$refs.tree.setCheckedKeys([]);
42       }
43     },
44 
45     data() {
46       return {
47         data2: [{
48           id: 1,
49           label: '一级 1',
50           children: [{
51             id: 4,
52             label: '二级 1-1',
53             children: [{
54               id: 9,
55               label: '三级 1-1-1'
56             }, {
57               id: 10,
58               label: '三级 1-1-2'
59             }]
60           }]
61         }, {
62           id: 2,
63           label: '一级 2',
64           children: [{
65             id: 5,
66             label: '二级 2-1'
67           }, {
68             id: 6,
69             label: '二级 2-2'
70           }]
71         }, {
72           id: 3,
73           label: '一级 3',
74           children: [{
75             id: 7,
76             label: '二级 3-1'
77           }, {
78             id: 8,
79             label: '二级 3-2'
80           }]
81         }],
82         defaultProps: {
83           children: 'children',
84           label: 'label'
85         }
86       };
87     }
88   };
89 </script>
View Code

 

自定义节点内容

节点的内容支持自定义,可以在节点区添加按钮或图标等内容

可以通过两种方法进行树节点内容的自定义:render-content和 scoped slot。使用render-content指定渲染函数,该函数返回需要的节点区内容即可。渲染函数的用法请参考 Vue 文档。使用 scoped slot 会传入两个参数node和data,分别表示当前节点的 Node 对象和当前节点的数据。注意:由于 jsfiddle 不支持 JSX 语法,所以render-content示例在 jsfiddle 中无法运行。但是在实际的项目中,只要正确地配置了相关依赖,就可以正常运行。

  1 <div class="custom-tree-container">
  2   <div class="block">
  3     <p>使用 render-content</p>
  4     <el-tree
  5       :data="data4"
  6       show-checkbox
  7       node-key="id"
  8       default-expand-all
  9       :expand-on-click-node="false"
 10       :render-content="renderContent">
 11     </el-tree>
 12   </div>
 13   <div class="block">
 14     <p>使用 scoped slot</p>
 15     <el-tree
 16       :data="data5"
 17       show-checkbox
 18       node-key="id"
 19       default-expand-all
 20       :expand-on-click-node="false">
 21       <span class="custom-tree-node" slot-scope="{ node, data }">
 22         <span>{{ node.label }}</span>
 23         <span>
 24           <el-button
 25             type="text"
 26             size="mini"
 27             @click="() => append(data)">
 28             Append
 29           </el-button>
 30           <el-button
 31             type="text"
 32             size="mini"
 33             @click="() => remove(node, data)">
 34             Delete
 35           </el-button>
 36         </span>
 37       </span>
 38     </el-tree>
 39   </div>
 40 </div>
 41 
 42 <script>
 43   let id = 1000;
 44 
 45   export default {
 46     data() {
 47       const data = [{
 48         id: 1,
 49         label: '一级 1',
 50         children: [{
 51           id: 4,
 52           label: '二级 1-1',
 53           children: [{
 54             id: 9,
 55             label: '三级 1-1-1'
 56           }, {
 57             id: 10,
 58             label: '三级 1-1-2'
 59           }]
 60         }]
 61       }, {
 62         id: 2,
 63         label: '一级 2',
 64         children: [{
 65           id: 5,
 66           label: '二级 2-1'
 67         }, {
 68           id: 6,
 69           label: '二级 2-2'
 70         }]
 71       }, {
 72         id: 3,
 73         label: '一级 3',
 74         children: [{
 75           id: 7,
 76           label: '二级 3-1'
 77         }, {
 78           id: 8,
 79           label: '二级 3-2'
 80         }]
 81       }];
 82       return {
 83         data4: JSON.parse(JSON.stringify(data)),
 84         data5: JSON.parse(JSON.stringify(data))
 85       }
 86     },
 87 
 88     methods: {
 89       append(data) {
 90         const newChild = { id: id++, label: 'testtest', children: [] };
 91         if (!data.children) {
 92           this.$set(data, 'children', []);
 93         }
 94         data.children.push(newChild);
 95       },
 96 
 97       remove(node, data) {
 98         const parent = node.parent;
 99         const children = parent.data.children || parent.data;
100         const index = children.findIndex(d => d.id === data.id);
101         children.splice(index, 1);
102       },
103 
104       renderContent(h, { node, data, store }) {
105         return (
106           <span class="custom-tree-node">
107             <span>{node.label}</span>
108             <span>
109               <el-button size="mini" type="text" on-click={ () => this.append(data) }>Append</el-button>
110               <el-button size="mini" type="text" on-click={ () => this.remove(node, data) }>Delete</el-button>
111             </span>
112           </span>);
113       }
114     }
115   };
116 </script>
117 
118 <style>
119   .custom-tree-node {
120     flex: 1;
121     display: flex;
122     align-items: center;
123     justify-content: space-between;
124     font-size: 14px;
125     padding-right: 8px;
126   }
127 </style>
View Code

 

节点过滤

通过关键字过滤树节点

在需要对节点进行过滤时,调用 Tree 实例的filter方法,参数为关键字。需要注意的是,此时需要设置filter-node-method,值为过滤函数。

 1 <el-input
 2   placeholder="输入关键字进行过滤"
 3   v-model="filterText">
 4 </el-input>
 5 
 6 <el-tree
 7   class="filter-tree"
 8   :data="data2"
 9   :props="defaultProps"
10   default-expand-all
11   :filter-node-method="filterNode"
12   ref="tree2">
13 </el-tree>
14 
15 <script>
16   export default {
17     watch: {
18       filterText(val) {
19         this.$refs.tree2.filter(val);
20       }
21     },
22 
23     methods: {
24       filterNode(value, data) {
25         if (!value) return true;
26         return data.label.indexOf(value) !== -1;
27       }
28     },
29 
30     data() {
31       return {
32         filterText: '',
33         data2: [{
34           id: 1,
35           label: '一级 1',
36           children: [{
37             id: 4,
38             label: '二级 1-1',
39             children: [{
40               id: 9,
41               label: '三级 1-1-1'
42             }, {
43               id: 10,
44               label: '三级 1-1-2'
45             }]
46           }]
47         }, {
48           id: 2,
49           label: '一级 2',
50           children: [{
51             id: 5,
52             label: '二级 2-1'
53           }, {
54             id: 6,
55             label: '二级 2-2'
56           }]
57         }, {
58           id: 3,
59           label: '一级 3',
60           children: [{
61             id: 7,
62             label: '二级 3-1'
63           }, {
64             id: 8,
65             label: '二级 3-2'
66           }]
67         }],
68         defaultProps: {
69           children: 'children',
70           label: 'label'
71         }
72       };
73     }
74   };
75 </script>
View Code

 

手风琴模式

对于同一级的节点,每次只能展开一个

 1 <el-tree
 2   :data="data"
 3   :props="defaultProps"
 4   accordion
 5   @node-click="handleNodeClick">
 6 </el-tree>
 7 
 8 <script>
 9   export default {
10     data() {
11       return {
12         data: [{
13           label: '一级 1',
14           children: [{
15             label: '二级 1-1',
16             children: [{
17               label: '三级 1-1-1'
18             }]
19           }]
20         }, {
21           label: '一级 2',
22           children: [{
23             label: '二级 2-1',
24             children: [{
25               label: '三级 2-1-1'
26             }]
27           }, {
28             label: '二级 2-2',
29             children: [{
30               label: '三级 2-2-1'
31             }]
32           }]
33         }, {
34           label: '一级 3',
35           children: [{
36             label: '二级 3-1',
37             children: [{
38               label: '三级 3-1-1'
39             }]
40           }, {
41             label: '二级 3-2',
42             children: [{
43               label: '三级 3-2-1'
44             }]
45           }]
46         }],
47         defaultProps: {
48           children: 'children',
49           label: 'label'
50         }
51       };
52     },
53     methods: {
54       handleNodeClick(data) {
55         console.log(data);
56       }
57     }
58   };
59 </script>
View Code

 

Attributes

参数说明类型可选值默认值
data 展示数据 array — —
empty-text 内容为空的时候展示的文本 String — —
node-key 每个树节点用来作为唯一标识的属性,整棵树应该是唯一的 String — —
props 配置选项,具体看下表 object — —
render-after-expand 是否在第一次展开某个树节点后才渲染其子节点 boolean — true
load 加载子树数据的方法,仅当 lazy 属性为true 时生效 function(node, resolve) — —
render-content 树节点的内容区的渲染 Function Function(h, { node, data, store } — —
highlight-current 是否高亮当前选中节点,默认值是 false。 boolean — false
default-expand-all 是否默认展开所有节点 boolean — false
expand-on-click-node 是否在点击节点的时候展开或者收缩节点, 默认值为 true,如果为 false,则只有点箭头图标的时候才会展开或者收缩节点。 boolean — true
auto-expand-parent 展开子节点的时候是否自动展开父节点 boolean — true
default-expanded-keys 默认展开的节点的 key 的数组 array — —
show-checkbox 节点是否可被选择 boolean — false
check-strictly 在显示复选框的情况下,是否严格的遵循父子不互相关联的做法,默认为 false boolean — false
default-checked-keys 默认勾选的节点的 key 的数组 array — —
filter-node-method 对树节点进行筛选时执行的方法,返回 true 表示这个节点可以显示,返回 false 则表示这个节点会被隐藏 Function(value, data, node) — —
accordion 是否每次只打开一个同级树节点展开 boolean — false
indent 相邻级节点间的水平缩进,单位为像素 number — 16
lazy 是否懒加载子节点,需与 load 方法结合使用 boolean — false

props

参数说明类型可选值默认值
label 指定节点标签为节点对象的某个属性值 string, function(data, node) — —
children 指定子树为节点对象的某个属性值 string — —
disabled 指定节点选择框是否禁用为节点对象的某个属性值 boolean, function(data, node) — —
isLeaf 指定节点是否为叶子节点,仅在指定了 lazy 属性的情况下生效 boolean, function(data, node) — —

方法

Tree 内部使用了 Node 类型的对象来包装用户传入的数据,用来保存目前节点的状态。 Tree 拥有如下方法:

方法名说明参数
filter 对树节点进行筛选操作 接收一个任意类型的参数,该参数会在 filter-node-method 中作为第一个参数
updateKeyChildren 通过 keys 设置节点子元素,使用此方法必须设置 node-key 属性 (key, data) 接收两个参数,1. 节点 key 2. 节点数据的数组
getCheckedNodes 若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点所组成的数组 (leafOnly) 接收一个 boolean 类型的参数,若为 true 则仅返回被选中的叶子节点,默认值为 false
setCheckedNodes 设置目前勾选的节点,使用此方法必须设置 node-key 属性 (nodes) 接收勾选节点数据的数组
getCheckedKeys 若节点可被选择(即 show-checkbox 为 true),则返回目前被选中的节点的 key 所组成的数组 (leafOnly) 接收一个 boolean 类型的参数,若为 true 则仅返回被选中的叶子节点的 keys,默认值为 false
setCheckedKeys 通过 keys 设置目前勾选的节点,使用此方法必须设置 node-key 属性 (keys, leafOnly) 接收两个参数,1. 勾选节点的 key 的数组 2. boolean 类型的参数,若为 true则仅设置叶子节点的选中状态,默认值为 false
setChecked 通过 key / data 设置某个节点的勾选状态,使用此方法必须设置 node-key 属性 (key/data, checked, deep) 接收三个参数,1. 勾选节点的 key 或者 data 2. boolean 类型,节点是否选中 3. boolean 类型,是否设置子节点 ,默认为 false
getHalfCheckedNodes 若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点所组成的数组 -
getHalfCheckedKeys 若节点可被选择(即 show-checkbox 为 true),则返回目前半选中的节点的 key 所组成的数组 -
getCurrentKey 获取当前被选中节点的 key,使用此方法必须设置 node-key 属性,若没有节点被选中则返回 null —
getCurrentNode 获取当前被选中节点的 node,若没有节点被选中则返回 null —
setCurrentKey 通过 key 设置某个节点的当前选中状态,使用此方法必须设置 node-key 属性 (key) 待被选节点的 key
setCurrentNode 通过 node 设置某个节点的当前选中状态,使用此方法必须设置 node-key 属性 (node) 待被选节点的 node
getNode 根据 data 或者 key 拿到 Tree 组件中的 node (data) 要获得 node 的 key 或者 data
remove 删除 Tree 中的一个节点 (data) 要删除的节点的 data、key 或者 node
append 为 Tree 中的一个节点追加一个子节点 (data, parentNode) 接收两个参数,1. 要追加的子节点的 data 2. 子节点的 parent 的 data、key 或者 node
insertBefore 为 Tree 的一个节点的前面增加一个节点 (data, refNode) 接收两个参数,1. 要增加的节点的 data 2. 要增加的节点的后一个节点的 data、key 或者 node
insertAfter 为 Tree 的一个节点的后面增加一个节点 (data, refNode) 接收两个参数,1. 要增加的节点的 data 2. 要增加的节点的前一个节点的 data、key 或者 node

Events

事件名称说明回调参数
node-click 节点被点击时的回调 共三个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。
node-contextmenu 当某一节点被鼠标右键点击时会触发该事件 共四个参数,依次为:event、传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。
check-change 节点选中状态发生变化时的回调 共三个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点本身是否被选中、节点的子树中是否有被选中的节点
check 当复选框被点击的时候触发 共两个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、树目前的选中状态对象,包含 checkedNodes、checkedKeys、halfCheckedNodes、halfCheckedKeys 四个属性
current-change 当前选中节点变化时触发的事件 共两个参数,依次为:当前节点的数据,当前节点的 Node 对象
node-expand 节点被展开时触发的事件 共三个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。
node-collapse 节点被关闭时触发的事件 共三个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。

Scoped slot

name说明
— 自定义树节点的内容,参数为 { node, data }
posted @ 2018-03-14 06:43  大姐姐小姐姐  阅读(9241)  评论(0)    收藏  举报