Tree 树形控件

概述

文件夹、组织架构、生物分类、国家地区等等,世间万物的大多数结构都是树形结构。使用树控件可以完整展现其中的层级关系,并具有展开收起选择等交互功能。

代码示例

Tree 树形控件 - 图1

基础用法

最简单的用法,展示可选中,默认展开功能。

  1. <template>
  2. <Tree :data="data1"></Tree>
  3. </template>
  4. <script>
  5. export default {
  6. data () {
  7. return {
  8. data1: [
  9. {
  10. title: 'parent 1',
  11. expand: true,
  12. children: [
  13. {
  14. title: 'parent 1-1',
  15. expand: true,
  16. children: [
  17. {
  18. title: 'leaf 1-1-1'
  19. },
  20. {
  21. title: 'leaf 1-1-2'
  22. }
  23. ]
  24. },
  25. {
  26. title: 'parent 1-2',
  27. expand: true,
  28. children: [
  29. {
  30. title: 'leaf 1-2-1'
  31. },
  32. {
  33. title: 'leaf 1-2-1'
  34. }
  35. ]
  36. }
  37. ]
  38. }
  39. ]
  40. }
  41. }
  42. }
  43. </script>

Tree 树形控件 - 图2

可勾选

设置属性 show-checkbox 可以对节点进行勾选。

  1. <template>
  2. <Tree :data="data2" show-checkbox></Tree>
  3. </template>
  4. <script>
  5. export default {
  6. data () {
  7. return {
  8. data2: [
  9. {
  10. title: 'parent 1',
  11. expand: true,
  12. children: [
  13. {
  14. title: 'parent 1-1',
  15. expand: true,
  16. children: [
  17. {
  18. title: 'leaf 1-1-1'
  19. },
  20. {
  21. title: 'leaf 1-1-2'
  22. }
  23. ]
  24. },
  25. {
  26. title: 'parent 1-2',
  27. expand: true,
  28. children: [
  29. {
  30. title: 'leaf 1-2-1'
  31. },
  32. {
  33. title: 'leaf 1-2-1'
  34. }
  35. ]
  36. }
  37. ]
  38. }
  39. ]
  40. }
  41. }
  42. }
  43. </script>

Tree 树形控件 - 图3

异步加载子节点

使用 load-data 属性可以异步加载子节点,需要给数据增加 loading 来标识当前是否在加载中。

load-data 第一个参数为当前节点信息;执行 load-data 的第二个参数,将需要添加的数据传入。

如果某节点不包含 loadingchildren 字段,则不会应用异步加载效果。

  1. <template>
  2. <Tree :data="data3" :load-data="loadData" show-checkbox></Tree>
  3. </template>
  4. <script>
  5. export default {
  6. data () {
  7. return {
  8. data3: [
  9. {
  10. title: 'parent',
  11. loading: false,
  12. children: []
  13. }
  14. ]
  15. }
  16. },
  17. methods: {
  18. loadData (item, callback) {
  19. setTimeout(() => {
  20. const data = [
  21. {
  22. title: 'children',
  23. loading: false,
  24. children: []
  25. },
  26. {
  27. title: 'children',
  28. loading: false,
  29. children: []
  30. }
  31. ];
  32. callback(data);
  33. }, 1000);
  34. }
  35. }
  36. }
  37. </script>

Tree 树形控件 - 图4

默认展开、选中、勾选和禁用

给节点设置 expandselectedcheckeddisabled 可以将节点设置为展开、选中、勾选和禁用。

设置属性 multiple 可进行多选。

  1. <template>
  2. <Tree :data="data4" show-checkbox multiple></Tree>
  3. </template>
  4. <script>
  5. export default {
  6. data () {
  7. return {
  8. data4: [
  9. {
  10. title: 'parent 1',
  11. expand: true,
  12. selected: true,
  13. children: [
  14. {
  15. title: 'parent 1-1',
  16. expand: true,
  17. children: [
  18. {
  19. title: 'leaf 1-1-1',
  20. disabled: true
  21. },
  22. {
  23. title: 'leaf 1-1-2'
  24. }
  25. ]
  26. },
  27. {
  28. title: 'parent 1-2',
  29. expand: true,
  30. children: [
  31. {
  32. title: 'leaf 1-2-1',
  33. checked: true
  34. },
  35. {
  36. title: 'leaf 1-2-1'
  37. }
  38. ]
  39. }
  40. ]
  41. }
  42. ]
  43. }
  44. }
  45. }
  46. </script>

Tree 树形控件 - 图5

自定义节点内容

使用强大的 Render 函数可以自定义节点显示内容和交互,比如添加图标,按钮等。

Render 函数的第二个参数,包含三个字段:

  • root :树的根节点
  • node :当前节点
  • data :当前节点的数据
  • 通过合理地使用 root、node 和 data 可以实现各种效果,其中,iView 给每个节点都设置了一个 nodeKey 字段,用来标识节点的 id。

Render 函数分两种,一种是给当前树的每个节点都设置同样的渲染内容,此 render 通过 Tree 组件的属性 render 传递;另一种是单独给某个节点设置,在该节点的 render 字段内设置;同时设置时,会优先使用当前节点的 Render 函数。

学习 Render 函数的内容

  1. <template>
  2. <Tree :data="data5" :render="renderContent"></Tree>
  3. </template>
  4. <script>
  5. export default {
  6. data () {
  7. return {
  8. data5: [
  9. {
  10. title: 'parent 1',
  11. expand: true,
  12. render: (h, { root, node, data }) => {
  13. return h('span', {
  14. style: {
  15. display: 'inline-block',
  16. width: '100%'
  17. }
  18. }, [
  19. h('span', [
  20. h('Icon', {
  21. props: {
  22. type: 'ios-folder-outline'
  23. },
  24. style: {
  25. marginRight: '8px'
  26. }
  27. }),
  28. h('span', data.title)
  29. ]),
  30. h('span', {
  31. style: {
  32. display: 'inline-block',
  33. float: 'right',
  34. marginRight: '32px'
  35. }
  36. }, [
  37. h('Button', {
  38. props: Object.assign({}, this.buttonProps, {
  39. icon: 'ios-add',
  40. type: 'primary'
  41. }),
  42. style: {
  43. width: '64px'
  44. },
  45. on: {
  46. click: () => { this.append(data) }
  47. }
  48. })
  49. ])
  50. ]);
  51. },
  52. children: [
  53. {
  54. title: 'child 1-1',
  55. expand: true,
  56. children: [
  57. {
  58. title: 'leaf 1-1-1',
  59. expand: true
  60. },
  61. {
  62. title: 'leaf 1-1-2',
  63. expand: true
  64. }
  65. ]
  66. },
  67. {
  68. title: 'child 1-2',
  69. expand: true,
  70. children: [
  71. {
  72. title: 'leaf 1-2-1',
  73. expand: true
  74. },
  75. {
  76. title: 'leaf 1-2-1',
  77. expand: true
  78. }
  79. ]
  80. }
  81. ]
  82. }
  83. ],
  84. buttonProps: {
  85. type: 'default',
  86. size: 'small',
  87. }
  88. }
  89. },
  90. methods: {
  91. renderContent (h, { root, node, data }) {
  92. return h('span', {
  93. style: {
  94. display: 'inline-block',
  95. width: '100%'
  96. }
  97. }, [
  98. h('span', [
  99. h('Icon', {
  100. props: {
  101. type: 'ios-paper-outline'
  102. },
  103. style: {
  104. marginRight: '8px'
  105. }
  106. }),
  107. h('span', data.title)
  108. ]),
  109. h('span', {
  110. style: {
  111. display: 'inline-block',
  112. float: 'right',
  113. marginRight: '32px'
  114. }
  115. }, [
  116. h('Button', {
  117. props: Object.assign({}, this.buttonProps, {
  118. icon: 'ios-add'
  119. }),
  120. style: {
  121. marginRight: '8px'
  122. },
  123. on: {
  124. click: () => { this.append(data) }
  125. }
  126. }),
  127. h('Button', {
  128. props: Object.assign({}, this.buttonProps, {
  129. icon: 'ios-remove'
  130. }),
  131. on: {
  132. click: () => { this.remove(root, node, data) }
  133. }
  134. })
  135. ])
  136. ]);
  137. },
  138. append (data) {
  139. const children = data.children || [];
  140. children.push({
  141. title: 'appended node',
  142. expand: true
  143. });
  144. this.$set(data, 'children', children);
  145. },
  146. remove (root, node, data) {
  147. const parentKey = root.find(el => el === node).parent;
  148. const parent = root.find(el => el.nodeKey === parentKey).node;
  149. const index = parent.children.indexOf(data);
  150. parent.children.splice(index, 1);
  151. }
  152. }
  153. }
  154. </script>

API

Tree props

属性说明类型默认值
data可嵌套的节点属性的数组,生成 tree 的数据Array[]
multiple是否支持多选Booleanfalse
show-checkbox是否显示多选框Booleanfalse
empty-text没有数据时的提示String暂无数据
load-data异步加载数据的方法,见示例Function-
render自定义渲染内容,见示例Function-
children-key定义子节点键Stringchildren
check-strictly在显示复选框的情况下,是否严格的遵循父子不互相关联的做法Booleanfalse
check-directly 3.3.0开启后,在 show-checkbox 模式下,select 的交互也将转为 checkBooleanfalse

Tree events

事件名说明返回值
on-select-change点击树节点时触发当前已选中的节点数组、当前项
on-check-change点击复选框时触发当前已勾选节点的数组、当前项
on-toggle-expand展开和收起子列表时触发当前节点的数据

Tree methods

方法名说明参数
getCheckedNodes获取被勾选的节点
getSelectedNodes获取被选中的节点
getCheckedAndIndeterminateNodes获取选中及半选节点

children

属性说明类型默认值
title标题String | Element String-
expand是否展开直子节点Booleanfalse
disabled禁掉响应Booleanfalse
disableCheckbox禁掉 checkboxBooleanfalse
selected是否选中子节点Booleanfalse
checked是否勾选(如果勾选,子节点也会全部勾选)Booleanfalse
children子节点属性数组Array-
render自定义当前节点渲染内容,见示例Function-