当前位置:   article > 正文

ElementUI浅尝辄止21:Tree 树形控件_element树形控件

element树形控件

树形组件:用清晰的层级结构展示信息,可展开或折叠。

树组件使用挺频繁的,常见于侧边栏树形目录、树形下拉选项按钮或搜索查询树形信息选项

1.如何使用?

基础的树形结构展示

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

2.可选择

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

  1. //可以动态加载节点数据。
  2. <el-tree
  3. :props="props"
  4. :load="loadNode"
  5. lazy
  6. show-checkbox
  7. @check-change="handleCheckChange">
  8. </el-tree>
  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. var hasChild;
  33. if (node.data.name === 'region1') {
  34. hasChild = true;
  35. } else if (node.data.name === 'region2') {
  36. hasChild = false;
  37. } else {
  38. hasChild = Math.random() > 0.5;
  39. }
  40. setTimeout(() => {
  41. var data;
  42. if (hasChild) {
  43. data = [{
  44. name: 'zone' + this.count++
  45. }, {
  46. name: 'zone' + this.count++
  47. }];
  48. } else {
  49. data = [];
  50. }
  51. resolve(data);
  52. }, 500);
  53. }
  54. }
  55. };
  56. </script>

3.懒加载自定义叶子节点

  1. /*由于在点击节点时才进行该层数据的获取,默认情况下 Tree 无法预知某个节点是否为叶子节点,所以会为每个节点添加一个下拉按钮,如果节点没有下层数据,则点击后下拉按钮会消失。同时,你也可以提前告知 Tree 某个节点是否为叶子节点,从而避免在叶子节点前渲染下拉按钮。*/
  2. <el-tree
  3. :props="props"
  4. :load="loadNode"
  5. lazy
  6. show-checkbox>
  7. </el-tree>
  8. <script>
  9. export default {
  10. data() {
  11. return {
  12. props: {
  13. label: 'name',
  14. children: 'zones',
  15. isLeaf: 'leaf'
  16. },
  17. };
  18. },
  19. methods: {
  20. loadNode(node, resolve) {
  21. if (node.level === 0) {
  22. return resolve([{ name: 'region' }]);
  23. }
  24. if (node.level > 1) return resolve([]);
  25. setTimeout(() => {
  26. const data = [{
  27. name: 'leaf',
  28. leaf: true
  29. }, {
  30. name: 'zone'
  31. }];
  32. resolve(data);
  33. }, 500);
  34. }
  35. }
  36. };
  37. </script>

4.默认展开和默认选中

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

  1. /*分别通过default-expanded-keys和default-checked-keys设置默认展开和默认选中的节点。需要注意的是,此时必须设置node-key,其值为节点数据中的一个字段名,该字段在整棵树中是唯一的。*/
  2. <el-tree
  3. :data="data"
  4. show-checkbox
  5. node-key="id"
  6. :default-expanded-keys="[2, 3]"
  7. :default-checked-keys="[5]"
  8. :props="defaultProps">
  9. </el-tree>
  10. <script>
  11. export default {
  12. data() {
  13. return {
  14. data: [{
  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>

5.禁用状态

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

  1. //通过disabled设置禁用状态。
  2. <el-tree
  3. :data="data"
  4. show-checkbox
  5. node-key="id"
  6. :default-expanded-keys="[2, 3]"
  7. :default-checked-keys="[5]">
  8. </el-tree>
  9. <script>
  10. export default {
  11. data() {
  12. return {
  13. data: [{
  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>

6.树节点的选择

  1. /*如何获取和设置选中节点。获取和设置各有两种方式:通过 node 或通过 key。如果需要通过 key 来获取或设置,则必须设置node-key。*/
  2. <el-tree
  3. :data="data"
  4. show-checkbox
  5. default-expand-all
  6. node-key="id"
  7. ref="tree"
  8. highlight-current
  9. :props="defaultProps">
  10. </el-tree>
  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. <script>
  19. export default {
  20. methods: {
  21. getCheckedNodes() {
  22. console.log(this.$refs.tree.getCheckedNodes());
  23. },
  24. getCheckedKeys() {
  25. console.log(this.$refs.tree.getCheckedKeys());
  26. },
  27. setCheckedNodes() {
  28. this.$refs.tree.setCheckedNodes([{
  29. id: 5,
  30. label: '二级 2-1'
  31. }, {
  32. id: 9,
  33. label: '三级 1-1-1'
  34. }]);
  35. },
  36. setCheckedKeys() {
  37. this.$refs.tree.setCheckedKeys([3]);
  38. },
  39. resetChecked() {
  40. this.$refs.tree.setCheckedKeys([]);
  41. }
  42. },
  43. data() {
  44. return {
  45. data: [{
  46. id: 1,
  47. label: '一级 1',
  48. children: [{
  49. id: 4,
  50. label: '二级 1-1',
  51. children: [{
  52. id: 9,
  53. label: '三级 1-1-1'
  54. }, {
  55. id: 10,
  56. label: '三级 1-1-2'
  57. }]
  58. }]
  59. }, {
  60. id: 2,
  61. label: '一级 2',
  62. children: [{
  63. id: 5,
  64. label: '二级 2-1'
  65. }, {
  66. id: 6,
  67. label: '二级 2-2'
  68. }]
  69. }, {
  70. id: 3,
  71. label: '一级 3',
  72. children: [{
  73. id: 7,
  74. label: '二级 3-1'
  75. }, {
  76. id: 8,
  77. label: '二级 3-2'
  78. }]
  79. }],
  80. defaultProps: {
  81. children: 'children',
  82. label: 'label'
  83. }
  84. };
  85. }
  86. };
  87. </script>

7.自定义节点内容

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

  1. /*可以通过两种方法进行树节点内容的自定义:render-content和 scoped slot。使用render-content指定渲染函数,该函数返回需要的节点区内容即可。渲染函数的用法请参考 Vue 文档。使用 scoped slot 会传入两个参数node和data,分别表示当前节点的 Node 对象和当前节点的数据。注意:由于 jsfiddle 不支持 JSX 语法,所以render-content示例在 jsfiddle 中无法运行。但是在实际的项目中,只要正确地配置了相关依赖,就可以正常运行。*/
  2. <div class="custom-tree-container">
  3. <div class="block">
  4. <p>使用 render-content</p>
  5. <el-tree
  6. :data="data"
  7. show-checkbox
  8. node-key="id"
  9. default-expand-all
  10. :expand-on-click-node="false"
  11. :render-content="renderContent">
  12. </el-tree>
  13. </div>
  14. <div class="block">
  15. <p>使用 scoped slot</p>
  16. <el-tree
  17. :data="data"
  18. show-checkbox
  19. node-key="id"
  20. default-expand-all
  21. :expand-on-click-node="false">
  22. <span class="custom-tree-node" slot-scope="{ node, data }">
  23. <span>{{ node.label }}</span>
  24. <span>
  25. <el-button
  26. type="text"
  27. size="mini"
  28. @click="() => append(data)">
  29. Append
  30. </el-button>
  31. <el-button
  32. type="text"
  33. size="mini"
  34. @click="() => remove(node, data)">
  35. Delete
  36. </el-button>
  37. </span>
  38. </span>
  39. </el-tree>
  40. </div>
  41. </div>
  42. <script>
  43. let id = 1000;
  44. export default {
  45. data() {
  46. const data = [{
  47. id: 1,
  48. label: '一级 1',
  49. children: [{
  50. id: 4,
  51. label: '二级 1-1',
  52. children: [{
  53. id: 9,
  54. label: '三级 1-1-1'
  55. }, {
  56. id: 10,
  57. label: '三级 1-1-2'
  58. }]
  59. }]
  60. }, {
  61. id: 2,
  62. label: '一级 2',
  63. children: [{
  64. id: 5,
  65. label: '二级 2-1'
  66. }, {
  67. id: 6,
  68. label: '二级 2-2'
  69. }]
  70. }, {
  71. id: 3,
  72. label: '一级 3',
  73. children: [{
  74. id: 7,
  75. label: '二级 3-1'
  76. }, {
  77. id: 8,
  78. label: '二级 3-2'
  79. }]
  80. }];
  81. return {
  82. data: JSON.parse(JSON.stringify(data)),
  83. data: JSON.parse(JSON.stringify(data))
  84. }
  85. },
  86. methods: {
  87. append(data) {
  88. const newChild = { id: id++, label: 'testtest', children: [] };
  89. if (!data.children) {
  90. this.$set(data, 'children', []);
  91. }
  92. data.children.push(newChild);
  93. },
  94. remove(node, data) {
  95. const parent = node.parent;
  96. const children = parent.data.children || parent.data;
  97. const index = children.findIndex(d => d.id === data.id);
  98. children.splice(index, 1);
  99. },
  100. renderContent(h, { node, data, store }) {
  101. return (
  102. <span class="custom-tree-node">
  103. <span>{node.label}</span>
  104. <span>
  105. <el-button size="mini" type="text" on-click={ () => this.append(data) }>Append</el-button>
  106. <el-button size="mini" type="text" on-click={ () => this.remove(node, data) }>Delete</el-button>
  107. </span>
  108. </span>);
  109. }
  110. }
  111. };
  112. </script>
  113. <style>
  114. .custom-tree-node {
  115. flex: 1;
  116. display: flex;
  117. align-items: center;
  118. justify-content: space-between;
  119. font-size: 14px;
  120. padding-right: 8px;
  121. }
  122. </style>

8.节点过滤

通过关键字过滤树节点

  1. /*在需要对节点进行过滤时,调用 Tree 实例的filter方法,参数为关键字。需要注意的是,此时需要设置filter-node-method,值为过滤函数。*/
  2. <el-input
  3. placeholder="输入关键字进行过滤"
  4. v-model="filterText">
  5. </el-input>
  6. <el-tree
  7. class="filter-tree"
  8. :data="data"
  9. :props="defaultProps"
  10. default-expand-all
  11. :filter-node-method="filterNode"
  12. ref="tree">
  13. </el-tree>
  14. <script>
  15. export default {
  16. watch: {
  17. filterText(val) {
  18. this.$refs.tree.filter(val);
  19. }
  20. },
  21. methods: {
  22. filterNode(value, data) {
  23. if (!value) return true;
  24. return data.label.indexOf(value) !== -1;
  25. }
  26. },
  27. data() {
  28. return {
  29. filterText: '',
  30. data: [{
  31. id: 1,
  32. label: '一级 1',
  33. children: [{
  34. id: 4,
  35. label: '二级 1-1',
  36. children: [{
  37. id: 9,
  38. label: '三级 1-1-1'
  39. }, {
  40. id: 10,
  41. label: '三级 1-1-2'
  42. }]
  43. }]
  44. }, {
  45. id: 2,
  46. label: '一级 2',
  47. children: [{
  48. id: 5,
  49. label: '二级 2-1'
  50. }, {
  51. id: 6,
  52. label: '二级 2-2'
  53. }]
  54. }, {
  55. id: 3,
  56. label: '一级 3',
  57. children: [{
  58. id: 7,
  59. label: '二级 3-1'
  60. }, {
  61. id: 8,
  62. label: '二级 3-2'
  63. }]
  64. }],
  65. defaultProps: {
  66. children: 'children',
  67. label: 'label'
  68. }
  69. };
  70. }
  71. };
  72. </script>

9.手风琴模式

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

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

 10.可拖拽节点

通过 draggable 属性可让节点变为可拖拽。

  1. <el-tree
  2. :data="data"
  3. node-key="id"
  4. default-expand-all
  5. @node-drag-start="handleDragStart"
  6. @node-drag-enter="handleDragEnter"
  7. @node-drag-leave="handleDragLeave"
  8. @node-drag-over="handleDragOver"
  9. @node-drag-end="handleDragEnd"
  10. @node-drop="handleDrop"
  11. draggable
  12. :allow-drop="allowDrop"
  13. :allow-drag="allowDrag">
  14. </el-tree>
  15. <script>
  16. export default {
  17. data() {
  18. return {
  19. data: [{
  20. id: 1,
  21. label: '一级 1',
  22. children: [{
  23. id: 4,
  24. label: '二级 1-1',
  25. children: [{
  26. id: 9,
  27. label: '三级 1-1-1'
  28. }, {
  29. id: 10,
  30. label: '三级 1-1-2'
  31. }]
  32. }]
  33. }, {
  34. id: 2,
  35. label: '一级 2',
  36. children: [{
  37. id: 5,
  38. label: '二级 2-1'
  39. }, {
  40. id: 6,
  41. label: '二级 2-2'
  42. }]
  43. }, {
  44. id: 3,
  45. label: '一级 3',
  46. children: [{
  47. id: 7,
  48. label: '二级 3-1'
  49. }, {
  50. id: 8,
  51. label: '二级 3-2',
  52. children: [{
  53. id: 11,
  54. label: '三级 3-2-1'
  55. }, {
  56. id: 12,
  57. label: '三级 3-2-2'
  58. }, {
  59. id: 13,
  60. label: '三级 3-2-3'
  61. }]
  62. }]
  63. }],
  64. defaultProps: {
  65. children: 'children',
  66. label: 'label'
  67. }
  68. };
  69. },
  70. methods: {
  71. handleDragStart(node, ev) {
  72. console.log('drag start', node);
  73. },
  74. handleDragEnter(draggingNode, dropNode, ev) {
  75. console.log('tree drag enter: ', dropNode.label);
  76. },
  77. handleDragLeave(draggingNode, dropNode, ev) {
  78. console.log('tree drag leave: ', dropNode.label);
  79. },
  80. handleDragOver(draggingNode, dropNode, ev) {
  81. console.log('tree drag over: ', dropNode.label);
  82. },
  83. handleDragEnd(draggingNode, dropNode, dropType, ev) {
  84. console.log('tree drag end: ', dropNode && dropNode.label, dropType);
  85. },
  86. handleDrop(draggingNode, dropNode, dropType, ev) {
  87. console.log('tree drop: ', dropNode.label, dropType);
  88. },
  89. allowDrop(draggingNode, dropNode, type) {
  90. if (dropNode.data.label === '二级 3-1') {
  91. return type !== 'inner';
  92. } else {
  93. return true;
  94. }
  95. },
  96. allowDrag(draggingNode) {
  97. return draggingNode.data.label.indexOf('三级 3-2-2') === -1;
  98. }
  99. }
  100. };
  101. </script>

上述内容即为Tree树组件的详细使用方法,若想深入浅出可以前往Tree组件 。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/码创造者/article/detail/903365
推荐阅读
相关标签
  

闽ICP备14008679号