element-ui中使用el-cascader实现全选功能

element-ui中使用el-cascader实现全选功能

一、效果图

在这里插入图片描述

二,主要代码

  <el-cascader
      v-model="searchForm.manualTagIds"
      :options="personOptions"
      @change="selectHandle"
      :props="{
          label: 'name',
          value: 'id',
          multiple: true,
          children: 'childTags',
      }"
      collapse-tags
      clearable
      :style="
          'width:' +
          this.$store.state.FormInputWidth.elFormItemWidth -
          25 +
          'px'
      "
      size="small"
      popper-class="TagIdsClass"
  ></el-cascader>
lastSelectedList: [], // 上次选中的数据
oneDimensionalList: [], //  源数据平铺成一级节点

 this.personOptions.unshift({ id: '全选', name: '全选' })
 
     getTreeList(list) {
            let _this = this
            for (let i = 0; i < list.length; i++) {
                let a = list[i]
                if (a.name !== '全选') {
                    this.oneDimensionalList.push(list[i])
                }
                if (a.childTags && a.childTags.length > 0) {
                    let res = _this.getTreeList(a.childTags)
                    if (res) {
                        return res
                    }
                }
            }
        },
        judgetAllSelected(node) {
            // 判断是否是全选,也就是看已选择的选中中包不包含"全选"
            let isAllSelected = false
            for (let i = 0; i < node.length; i++) {
                if (node[i][0] === '全选') {
                    isAllSelected = true
                    break
                }
            }
            return isAllSelected
        },
        loopSelectData(list, parentNode = []) {
            list.length > 0 &&
                list.forEach(e => {
                    let pNode = [...parentNode] // 注意这里必须是深拷贝,否则会由于引用类型赋值的是地址(指针),导致parentNode在pNode更新时,同时被更新
                    if (e.childTags && e.childTags.length > 0) {
                        pNode.push(e.id) // 1 11
                        this.loopSelectData(e.childTags, pNode)
                    } else {
                        if (parentNode.length > 0) {
                            this.searchForm.manualTagIds.push([...parentNode, e.id])
                        } else {
                            this.searchForm.manualTagIds.push([e.id])
                        }
                    }
                })
        },
        checkIsAddAllSelected() {
        //这里你要判断好你的dom是否正确
            let label1 = document
                .querySelectorAll('.el-cascader-panel')[1]
                .querySelector('.el-cascader-menu__wrap')
                .querySelectorAll('li')[0]
                .querySelectorAll('label')[0]
            let span1 = document
                .querySelectorAll('.el-cascader-panel')[1]
                .querySelector('.el-cascader-menu__wrap')
                .querySelectorAll('li')[0]
                .querySelectorAll('label')[0]
                .querySelectorAll('span')[0]
            // 获取所有的数据
            let list = this.personOptions // 原始数据列表
            if (this.oneDimensionalList.length === 0) {
                this.getTreeList(list) // 把所有的父子级平铺成一个一级列表
            }

            let origin = [...this.oneDimensionalList].filter(item => !item.childTags) //获取所有的叶子节点
            let nowList = [...this.searchForm.manualTagIds].filter(item => item[0] !== '全选')

            // 半选时, 如果有之前选过全选,要把全选过滤掉
            if (origin.length > nowList.length && nowList.length != 0) {
                this.searchForm.manualTagIds = this.searchForm.manualTagIds.filter(
                    item => item[0] !== '全选'
                )
                //设置半选样式,setTimeout可以解决样式渲染不上的问题
                setTimeout(function () {
                    label1.className = 'el-checkbox'
                    span1.className = 'el-checkbox__input is-indeterminate'
                }, 1)
            } else if (nowList.length == 0) {
                //不选时, 如果有之前选过全选,要把全选过滤掉
                this.searchForm.manualTagIds = this.searchForm.manualTagIds.filter(
                    item => item[0] !== '全选'
                )
                label1.className = 'el-checkbox'
                span1.className = 'el-checkbox__input'
            } else {
                // 当所有的数据都选择时, 要自动把全选勾选上  最后这种是:origin.length == nowList.length
                if (
                    this.searchForm.manualTagIds[0] &&
                    this.searchForm.manualTagIds[0][0] !== '全选'
                ) {
                    this.searchForm.manualTagIds = [['全选'], ...this.searchForm.manualTagIds]
                    label1.className = 'el-checkbox'
                    span1.className = 'el-checkbox__input is-checked'
                }
            }
        },
        // 选择级联选择器
        async selectHandle(e = []) {
            this.searchForm.manualTagIds = []

            // 选中的数据格式: [['全选'], [1, 2], [1, 3], [1, 4],[5, 6], [5, 7, 8],5, 7, 9],[10]]
            let list = this.personOptions //级联选择器的数据
            let current = [] // 获取当前选中的哪个数据,因为element文档中没有获取当前选中数据的方法,只能通过上次选中的数据和这次选中的数据进行比较来获取

            // 选中的所有数据list和上一次选中的list进行比较
            if (e.length >= this.lastSelectedList.length) {
                let keys = this.lastSelectedList.map(item => JSON.stringify(item))
                current = e.filter(item => !keys.includes(JSON.stringify(item)))
            } else {
                // 取消选中
                let keys = e.map(item => JSON.stringify(item))
                current = this.lastSelectedList.filter(item => !keys.includes(JSON.stringify(item)))
            }
            // 根据element的选中数据格式, 每一个选项都是一个列表, 列表第一项为父级value, 第二项为选中的子级value, ...以此类推
            const currentValue = current.length > 0 ? current[0][0] || '' : ''
            if (currentValue === '全选') {
                if (this.judgetAllSelected(e)) {
                    this.loopSelectData(list) //获取全选时回显的数据
                } else {
                    this.searchForm.manualTagIds = [] //不选
                }
            } else {
                this.searchForm.manualTagIds = e //半选
            }
            // 根据当前选择的数据(不包括全选)和全选时所有的数据--进行对比
            this.checkIsAddAllSelected()

            this.lastSelectedList = this.searchForm.manualTagIds // 保存上一次的选择结果
        },

链接: https://blog.csdn.net/qq_32166301/article/details/130198310

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值