el-cascader 父关联子,子不关联父

需求:选中父级,各个层级的子级都要选中,取消父级,下面所有子级取消选中;选中子级的时候,父级不选,取消子级,父级不取消。

思路:设置父子级完全不关联,checkStrictly属性设置为true,然后通过选择父级,手动将下面子级全部选中,反之,全部取消。

主要代码:

<template>
<div>
    <el-cascader
      ref="tree"
      v-model="ruleForm.org_list"
      size="small"
      placeholder="试试搜索"
      filterable
      style="width: 220px"
      clearable
      :show-all-levels="false"
      :props="{ multiple: true, emitPath: false, checkStrictly: true }"
      :options="orgOptions"
    />
</div>
</template>
<script>
import { checkedChildren, cancelChildren } from '@/utils/index'
export default {
    data() {
        return {
            ruleForm: {
               org_list: []             
            },
            orgOptions: [],
            checkedNode: '' // 保存上次选中的Node节点
        }    
    },
    watch: {
        'ruleForm.org_list': {
          deep: true,
          handler(newArr, oldArr) {
            if (newArr && newArr.length) {
              const current = this.findCurrentDepartment(newArr, oldArr)
              if (!current) return
              this.$nextTick(() => {
                if (current.type === 'checked') {
                  // 从级联选择器中取出内部的节点数组,找到当前节点
                  let targetNode = ''
                  this.checkedNode = this.$refs.tree.checkedNodes // 保存选中的节点, 取消用到
                  targetNode = this.$refs.tree.checkedNodes.find((item) => {
                    return item.value === current.value
                  })
                  if (targetNode) {
                    // 递归找出所有子孙节点,并手动勾选
                    checkedChildren([targetNode])
                    // 更新视图                    
                    this.$refs.tree.$refs.panel.calculateMultiCheckedValue()                    
                  }
                } else if (current.type === 'cancel') {
                  // 从级联选择器中取出内部的节点数组,找到当前节点
                  let targetNode = ''
                  targetNode = this.checkedNode.find((item) => {
                    return item.value === current.value
                  })                 
                  // console.log('选中的节点', this.checkedNode)
                  // console.log('===========', targetNode)
                  if (targetNode) {
                    // 递归找出所有子孙节点,并手动取消勾选
                    cancelChildren([targetNode])
                    // console.log('修改之后的节点树', cancelChildren([targetNode]))
                    // 更新视图
                    this.$refs.tree.$refs.panel.calculateMultiCheckedValue()                   
                  }
                }
              })
            }
          }
        }    
    },
    methods: {
      // 判断当前操作是选中还是取消
      findCurrentDepartment(newArr, oldArr) {
          const catchNewArr = [...newArr]
          const catchOldArr = [...oldArr]
          if (catchNewArr.length > catchOldArr.length) {
            // console.log('为添加')
            for (let i = 0; i < catchNewArr.length; i++) {
              const targetIndex = catchOldArr.indexOf(catchNewArr[i])
              if (targetIndex === -1) {
                return {
                  value: catchNewArr[i],
                  type: 'checked'
                }
              }
            }
          } else {
            // console.log('为取消')
            // console.log(catchOldArr, catchNewArr)
            for (let i = 0; i < catchOldArr.length; i++) {
              const targetIndex = catchNewArr.indexOf(catchOldArr[i])
              if (targetIndex === -1) {
                return {
                  value: catchOldArr[i],
                  type: 'cancel'
                }
              }
            }
          }
        },      
    },
}
</script>
// utils/index.js
// 处理树节点 选中父 子全部选上
export function checkedChildren(val) {
  for (const item of val) {
    item.checked = true
    if (item.children && item.children.length !== 0) {
      checkedChildren(item.children)
    }
  }
  return val
}
// 处理树节点 取消父 子全部取消
export function cancelChildren(val) {
  for (const item of val) {
    item.checked = false
    if (item.children && item.children.length !== 0) {
      cancelChildren(item.children)
    }
  }
  return val
}

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值