赞
踩
大家都知道el-tree可以很明显的通过选中来体现上下节点的父子选中状态,那么如果要求把后端把el-tree的数据结构,通过一个展开的list返回给你,使用el-checkbox组件渲染每一个节点,同时要求选中某一个节点,同时可以选中其父节点和子节点;取消也是一样。
首先el-checkbox是没有el-tree的check-strictly来严格遵循父子相关联的属性,那么想实现就需要
1. 向下递归查询点击节点的子节点。
2. 向上递归查询点击节点的父节点。
3. 通过indeterminate
属性用以表示 checkbox 的不确定状态,用来表示父节点的选中效果
使用el-checkbox实现el-tree父子关系选中效果
html部分:
- <template>
- <div>
- <el-checkbox
- v-for="(item, key) in labelList"
- :label="item.labelName"
- :key="key"
- v-model="item.checked"
- :indeterminate="item.isIndeterminate"
- @change="changeCheck(item)"
- ></el-checkbox>
- </div>
- </template>
JavaScript部分:
- <script>
- export default {
- data() {
- return {
- listQuery: {
- labelValue: [],
- },
- labelList: [
- // {
- // labelName: '根目录',
- // id: 1,
- // parentId: -1,
- // checked: false
- // },
- {
- labelName: '一级 1',
- id: 2,
- parentId: 1,
- checked: false,
- },
- {
- labelName: '一级 2',
- id: 3,
- parentId: 1,
- checked: false,
- },
- {
- labelName: '一级 3',
- id: 4,
- parentId: 1,
- checked: false,
- },
- {
- labelName: '二级 1-1',
- id: 5,
- parentId: 2,
- checked: false,
- },
- {
- labelName: '三级 1-1-1',
- id: 9,
- parentId: 5,
- checked: false,
- },
- {
- labelName: '三级 1-1-2',
- id: 10,
- parentId: 5,
- checked: false,
- },
- {
- labelName: '二级 2-1',
- id: 6,
- parentId: 3,
- checked: false,
- },
- {
- labelName: '二级 2-2',
- id: 7,
- parentId: 3,
- checked: false,
- },
- {
- labelName: '二级 3-1',
- id: 8,
- parentId: 4,
- checked: false,
- },
- {
- labelName: '二级 3-2',
- id: 11,
- parentId: 4,
- checked: false,
- },
- {
- labelName: '三级 3-2-1',
- id: 12,
- parentId: 11,
- checked: false,
- },
- {
- labelName: '三级 3-2-2',
- id: 13,
- parentId: 11,
- checked: false,
- },
- {
- labelName: '三级 3-2-3',
- id: 14,
- parentId: 11,
- checked: false,
- }
- ]
- }
- },
- methods: {
- changeCheck(row) {
- // 向下选中子级
- this.downRecursiveChildren(row)
-
- // 每次添加前先清空选中的标签的name数组
- this.listQuery.labelValue = []
- this.labelList.map((i) => {
- if (i.checked) {
- this.listQuery.labelValue.push(i.labelName)
- }
- })
- console.log('a', this.listQuery.labelValue)
- },
- downRecursiveChildren(row, isGrandChildren = false) {
- if (row.isIndeterminate) {
- row.isIndeterminate = false
- }
- this.labelList.forEach((item) => {
- // 判断点击的标签下,是否有子标签,如果有状态设置为true
- if (row.id === item.parentId) {
- item.checked = row.checked
- // 判断点击的标签下的子标签是否还有子级,如果有,递归调用,把所有子级全部选中
- if (this.labelList.some((v) => item.id === v.parentId)) {
- this.downRecursiveChildren(item, true)
- }
- }
- })
- // 如果没有了,return
- if (isGrandChildren) return
- this.upRecursiveParent(row)
- },
- // 向上寻找父级,添加状态
- upRecursiveParent(row) {
- // 获取点击标签的父标签
- let parentNode = this.labelList.find((v) => v.id == row.parentId)
- // 定义点击标签的兄弟数组
- let subing_list = []
-
- this.labelList.forEach((item) => {
- // 判断点击标签是否有相同的父级,如果有把所有的兄弟标签获取到
- if (item.parentId === row.parentId) {
- subing_list.push(item)
- console.log('2', subing_list)
- }
- })
- if (parentNode) {
- // 所有的兄弟节点全部选中且没有不确定状态, 需要选中父标签节点
- if (
- subing_list.every((item) => item.checked && !item.isIndeterminate)
- ) {
- // 全选中且没有不确定状态
- parentNode.checked = true
- parentNode.isIndeterminate = false
- console.log('3')
- } else if (
- // 所有的兄弟节点全部选中且没有不确定状态, 需要选中父标签节点
- subing_list.every((item) => !item.checked && !item.isIndeterminate)
- ) {
- // 全不选中并且没有不确定状态,不需要选中父标签节点
- parentNode.checked = false
- parentNode.isIndeterminate = false
- console.log('4')
- } else {
- // 有部分选中,父节点需要设置为半选状态
- parentNode.checked = false
- parentNode.isIndeterminate = true
- console.log('5', parentNode)
- }
- if (parentNode.parentId !== 1) {
- this.upRecursiveParent(parentNode)
- }
- }
- }
- },
- }
- </script>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。