当前位置:   article > 正文

开发需求15-使用el-checkbox组件实现el-tree组件的父子关联关系(非全选/全不选)

开发需求15-使用el-checkbox组件实现el-tree组件的父子关联关系(非全选/全不选)

需求描述:

大家都知道el-tree可以很明显的通过选中来体现上下节点的父子选中状态,那么如果要求把后端把el-tree的数据结构,通过一个展开的list返回给你,使用el-checkbox组件渲染每一个节点,同时要求选中某一个节点,同时可以选中其父节点和子节点;取消也是一样。

思路:

首先el-checkbox是没有el-tree的check-strictly来严格遵循父子相关联的属性,那么想实现就需要

1. 向下递归查询点击节点的子节点。

2. 向上递归查询点击节点的父节点。

3. 通过indeterminate 属性用以表示 checkbox 的不确定状态,用来表示父节点的选中效果

实现效果:

使用el-checkbox实现el-tree父子关系选中效果

代码实现:

html部分:

  1. <template>
  2. <div>
  3. <el-checkbox
  4. v-for="(item, key) in labelList"
  5. :label="item.labelName"
  6. :key="key"
  7. v-model="item.checked"
  8. :indeterminate="item.isIndeterminate"
  9. @change="changeCheck(item)"
  10. ></el-checkbox>
  11. </div>
  12. </template>

JavaScript部分:

  1. <script>
  2. export default {
  3. data() {
  4. return {
  5. listQuery: {
  6. labelValue: [],
  7. },
  8. labelList: [
  9. // {
  10. // labelName: '根目录',
  11. // id: 1,
  12. // parentId: -1,
  13. // checked: false
  14. // },
  15. {
  16. labelName: '一级 1',
  17. id: 2,
  18. parentId: 1,
  19. checked: false,
  20. },
  21. {
  22. labelName: '一级 2',
  23. id: 3,
  24. parentId: 1,
  25. checked: false,
  26. },
  27. {
  28. labelName: '一级 3',
  29. id: 4,
  30. parentId: 1,
  31. checked: false,
  32. },
  33. {
  34. labelName: '二级 1-1',
  35. id: 5,
  36. parentId: 2,
  37. checked: false,
  38. },
  39. {
  40. labelName: '三级 1-1-1',
  41. id: 9,
  42. parentId: 5,
  43. checked: false,
  44. },
  45. {
  46. labelName: '三级 1-1-2',
  47. id: 10,
  48. parentId: 5,
  49. checked: false,
  50. },
  51. {
  52. labelName: '二级 2-1',
  53. id: 6,
  54. parentId: 3,
  55. checked: false,
  56. },
  57. {
  58. labelName: '二级 2-2',
  59. id: 7,
  60. parentId: 3,
  61. checked: false,
  62. },
  63. {
  64. labelName: '二级 3-1',
  65. id: 8,
  66. parentId: 4,
  67. checked: false,
  68. },
  69. {
  70. labelName: '二级 3-2',
  71. id: 11,
  72. parentId: 4,
  73. checked: false,
  74. },
  75. {
  76. labelName: '三级 3-2-1',
  77. id: 12,
  78. parentId: 11,
  79. checked: false,
  80. },
  81. {
  82. labelName: '三级 3-2-2',
  83. id: 13,
  84. parentId: 11,
  85. checked: false,
  86. },
  87. {
  88. labelName: '三级 3-2-3',
  89. id: 14,
  90. parentId: 11,
  91. checked: false,
  92. }
  93. ]
  94. }
  95. },
  96. methods: {
  97. changeCheck(row) {
  98. // 向下选中子级
  99. this.downRecursiveChildren(row)
  100. // 每次添加前先清空选中的标签的name数组
  101. this.listQuery.labelValue = []
  102. this.labelList.map((i) => {
  103. if (i.checked) {
  104. this.listQuery.labelValue.push(i.labelName)
  105. }
  106. })
  107. console.log('a', this.listQuery.labelValue)
  108. },
  109. downRecursiveChildren(row, isGrandChildren = false) {
  110. if (row.isIndeterminate) {
  111. row.isIndeterminate = false
  112. }
  113. this.labelList.forEach((item) => {
  114. // 判断点击的标签下,是否有子标签,如果有状态设置为true
  115. if (row.id === item.parentId) {
  116. item.checked = row.checked
  117. // 判断点击的标签下的子标签是否还有子级,如果有,递归调用,把所有子级全部选中
  118. if (this.labelList.some((v) => item.id === v.parentId)) {
  119. this.downRecursiveChildren(item, true)
  120. }
  121. }
  122. })
  123. // 如果没有了,return
  124. if (isGrandChildren) return
  125. this.upRecursiveParent(row)
  126. },
  127. // 向上寻找父级,添加状态
  128. upRecursiveParent(row) {
  129. // 获取点击标签的父标签
  130. let parentNode = this.labelList.find((v) => v.id == row.parentId)
  131. // 定义点击标签的兄弟数组
  132. let subing_list = []
  133. this.labelList.forEach((item) => {
  134. // 判断点击标签是否有相同的父级,如果有把所有的兄弟标签获取到
  135. if (item.parentId === row.parentId) {
  136. subing_list.push(item)
  137. console.log('2', subing_list)
  138. }
  139. })
  140. if (parentNode) {
  141. // 所有的兄弟节点全部选中且没有不确定状态, 需要选中父标签节点
  142. if (
  143. subing_list.every((item) => item.checked && !item.isIndeterminate)
  144. ) {
  145. // 全选中且没有不确定状态
  146. parentNode.checked = true
  147. parentNode.isIndeterminate = false
  148. console.log('3')
  149. } else if (
  150. // 所有的兄弟节点全部选中且没有不确定状态, 需要选中父标签节点
  151. subing_list.every((item) => !item.checked && !item.isIndeterminate)
  152. ) {
  153. // 全不选中并且没有不确定状态,不需要选中父标签节点
  154. parentNode.checked = false
  155. parentNode.isIndeterminate = false
  156. console.log('4')
  157. } else {
  158. // 有部分选中,父节点需要设置为半选状态
  159. parentNode.checked = false
  160. parentNode.isIndeterminate = true
  161. console.log('5', parentNode)
  162. }
  163. if (parentNode.parentId !== 1) {
  164. this.upRecursiveParent(parentNode)
  165. }
  166. }
  167. }
  168. },
  169. }
  170. </script>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/439648
推荐阅读