customized-node.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <template>
  2. <div class="custom-tree-container">
  3. <p>Using render-content</p>
  4. <el-tree :data="dataSource" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false" :render-content="renderContent" />
  5. <p>Using scoped slot</p>
  6. <el-tree :data="dataSource" show-checkbox node-key="id" default-expand-all :expand-on-click-node="false">
  7. <template #default="{ node, data }">
  8. <span class="custom-tree-node">
  9. <span>{{ node.label }}</span>
  10. <span>
  11. <a @click="append(data)"> Append </a>
  12. <a style="margin-left: 8px" @click="remove(node, data)"> Delete </a>
  13. </span>
  14. </span>
  15. </template>
  16. </el-tree>
  17. </div>
  18. </template>
  19. <script lang="ts" setup>
  20. import { ref } from 'vue'
  21. import type Node from 'element-plus/es/components/tree/src/model/node'
  22. interface Tree {
  23. id: number
  24. label: string
  25. children?: Tree[]
  26. }
  27. let id = 1000
  28. const append = (data: Tree) => {
  29. const newChild = { id: id++, label: 'testtest', children: [] }
  30. if (!data.children) {
  31. data.children = []
  32. }
  33. data.children.push(newChild)
  34. dataSource.value = [...dataSource.value]
  35. }
  36. const remove = (node: Node, data: Tree) => {
  37. const parent = node.parent
  38. const children: Tree[] = parent.data.children || parent.data
  39. const index = children.findIndex(d => d.id === data.id)
  40. children.splice(index, 1)
  41. dataSource.value = [...dataSource.value]
  42. }
  43. const renderContent = (
  44. h,
  45. {
  46. node,
  47. data,
  48. store,
  49. }: {
  50. node: Node
  51. data: Tree
  52. store: Node['store']
  53. }
  54. ) => {
  55. return h(
  56. 'span',
  57. {
  58. class: 'custom-tree-node',
  59. },
  60. h('span', null, node.label),
  61. h(
  62. 'span',
  63. null,
  64. h(
  65. 'a',
  66. {
  67. onClick: () => append(data),
  68. },
  69. 'Append '
  70. ),
  71. h(
  72. 'a',
  73. {
  74. style: 'margin-left: 8px',
  75. onClick: () => remove(node, data),
  76. },
  77. 'Delete'
  78. )
  79. )
  80. )
  81. }
  82. const dataSource = ref<Tree[]>([
  83. {
  84. id: 1,
  85. label: 'Level one 1',
  86. children: [
  87. {
  88. id: 4,
  89. label: 'Level two 1-1',
  90. children: [
  91. {
  92. id: 9,
  93. label: 'Level three 1-1-1',
  94. },
  95. {
  96. id: 10,
  97. label: 'Level three 1-1-2',
  98. },
  99. ],
  100. },
  101. ],
  102. },
  103. {
  104. id: 2,
  105. label: 'Level one 2',
  106. children: [
  107. {
  108. id: 5,
  109. label: 'Level two 2-1',
  110. },
  111. {
  112. id: 6,
  113. label: 'Level two 2-2',
  114. },
  115. ],
  116. },
  117. {
  118. id: 3,
  119. label: 'Level one 3',
  120. children: [
  121. {
  122. id: 7,
  123. label: 'Level two 3-1',
  124. },
  125. {
  126. id: 8,
  127. label: 'Level two 3-2',
  128. },
  129. ],
  130. },
  131. ])
  132. </script>
  133. <style>
  134. .custom-tree-node {
  135. flex: 1;
  136. display: flex;
  137. align-items: center;
  138. justify-content: space-between;
  139. font-size: 14px;
  140. padding-right: 8px;
  141. }
  142. </style>