vue elementui 多选级联组件 全选功能

news/2024/7/7 20:04:44

Vue 封装 多选级联组件 支持全选功能

  • 使用方式和elm官方一致,原参数一致
  • 主要参数:
    • options:级联数菜单。多维数组
    • mulSelectedVal:绑定值。id集合。且取值最后一层id
    • collapseTags:是否tag展示
    • fieldNames:自定义结构字段名。key-value

组件展示

在这里插入图片描述
数据提交展示;
在这里插入图片描述

使用方式

<el-form-item label="城市: ">
     <multiple-cascader
         :mul-selected-val.sync="searchFormData.areaIds"
         :options="areaList" />
 </el-form-item>

组件源码

<template>
    <el-cascader
        ref="elCascaderRef"
        v-model="cascaderIds"
        :show-all-levels="false"
        :options="cascaderOptions"
        :props="{ multiple: true, ...fieldNames }"
        :collapse-tags="collapseTags"
        clearable filterable
        @change="onCascaderChange">
    </el-cascader>
</template>
  
<script>
// 缓存值 上一次选中值
let lastSelected = []
let dataLevel = 0  // 级联层级, 默认0层
export default {
    inheritAttrs: false,
    name: 'multiple-cascader',
    props: {
        // 选项
        options: {
            type: Array,
            default() {
                return [];
            }
        },
        // 已选中选项
        mulSelectedVal: {
            type: Array,
            default() {
                return [];
            }
        },
        collapseTags: {
            type: Boolean,
            default: true
        },
        // 自定义字段名
        fieldNames: {
            type: Object,
            default() {
                return {
                    label: 'name',
                    value: 'id',
                };
            }
        }
    },
    data() {
        return {
            cascaderIds: []
        };
    },
    computed: {
        // 级联列表
        cascaderOptions() {
            this.options.unshift({ children: null, id: '全选', name: '全选' })
            return this.options
        },

        // 全选值
        cascaderAllValue() {
            var model = []
            function tree2arr(arr, str, level) {
                dataLevel = (level + 1) // 实际数据结构是几层
                arr.forEach(it => {
                    let newStr = str.length ? [...str, it.id] : [it.id];
                    if (it.children) {
                        tree2arr(it.children, newStr, level + 1)
                    } else {
                        model.push(newStr)
                    }
                })
            }
            tree2arr(this.cascaderOptions, [], 0)
            return model
        },
    },
    methods: {
        onCascaderChange(node) {
            let current = [];   // 当前勾选项
            let isCheck = false  // 【勾选 | 反选】
            if(node.length >= lastSelected.length) {
                let keys = lastSelected.map(item => JSON.stringify(item))
                current = node.filter(item => !keys.includes(JSON.stringify(item)))
                isCheck = true
            }else {
                let keys = node.map(item => JSON.stringify(item))
                current = lastSelected.filter(item => !keys.includes(JSON.stringify(item)))
                isCheck = false
            }
            const currentValue = current.length > 0 ? current[0][0] || '' : ''
            
            if (currentValue === '全选') {
                if (isCheck) {
                    this.$set(this, 'cascaderIds', this.cascaderAllValue)
                } else {
                    this.$set(this, 'cascaderIds', [])
                }
            } else {
                // 除全选外
                let areaListAll = JSON.parse(JSON.stringify(this.cascaderAllValue))
                let firstValue = node.length > 0 ? node[0][0] || '' : ''
                if (firstValue !== '全选') { areaListAll.shift(); }
                
                if (node.length === areaListAll.length) {
                    this.$set(this, 'cascaderIds', [['全选'], ...this.cascaderIds])
                } else {
                    // 选中了全部,然后取消了某一个
                    if (firstValue === '全选') {
                        const ab = node.filter((item, index) => index >= 1)
                        this.$set(this, 'cascaderIds', ab)
                    }
                }
            }
            lastSelected = this.cascaderIds

            this.$nextTick(() => {
                let checkValue = this.$refs.elCascaderRef.getCheckedNodes() || []
                console.log('最深层级:', checkValue);
                // 更新绑定 筛选最后一层数据值
                this.$emit('update:mulSelectedVal', checkValue.filter(item => item.level === dataLevel).map(item => item.value));
                this.$emit('change', node)
            })
        },
    }
};
  </script>
  
  <style scoped lang="scss">
  </style>
  

http://lihuaxi.xjx100.cn/news/348138.html

相关文章

0119 动态规划 Day8

剑指 Offer 10- I. 斐波那契数列 写一个函数&#xff0c;输入 n &#xff0c;求斐波那契&#xff08;Fibonacci&#xff09;数列的第 n 项&#xff08;即 F(N)&#xff09;。斐波那契数列的定义如下&#xff1a; F(0) 0, F(1) 1 F(N) F(N - 1) F(N - 2), 其中 N > 1…

第16章 母函数

第16章 母函数 母函数是离散数学领域最意外、最有用的发明之一。粗略来讲&#xff0c;母函数将序列问题转化为代数问题。 组合数学中常常出现普通型母函数、指数型母函数、狄利克雷型母函数 16.1 无穷级数 通俗地说,母函数F(x)就是无穷级数 符号[xnx^nxn]F(x)表示母函数F(x…

JUC并发编程第九篇,原子操作类分类解析,LongAdder为什么这么快原理分析?

JUC并发编程第九篇&#xff0c;原子操作类分类解析&#xff0c;LongAdder为什么这么快原理分析&#xff1f;一、基本类型原子类二、数组类型原子类三、引用类型原子类四、对象的属性修改原子类五、原子操作增强类六、原理分析&#xff0c;LongAdder 为什么这么快&#xff1f;位…

网络安全之反序列化漏洞分析

简介 FastJson是alibaba的一款开源JSON解析库&#xff0c;可用于将Java对象转换为其JSON表示形式&#xff0c;也可以用于将JSON字符串转换为等效的Java对象分别通过toJSONString和parseObject/parse来实现序列化和反序列化。 使用 对于序列化的方法toJSONString()有多个重载…

基于风驱动算法优化的lssvm回归预测-附代码

基于风驱动算法优化的lssvm回归预测 - 附代码 文章目录基于风驱动算法优化的lssvm回归预测 - 附代码1.数据集2.lssvm模型3.基于风驱动算法优化的LSSVM4.测试结果5.Matlab代码摘要&#xff1a;为了提高最小二乘支持向量机&#xff08;lssvm&#xff09;的回归预测准确率&#xf…

欢迎报名Rust China Hackathon 2022 达坦科技组

12月4日下午&#xff0c;DatenLord就2022Rust China Hackathon大赛活动企业组&#xff08;达坦科技组&#xff09;的赛题进行了空中宣讲会。不仅对赛事流程进行了全面的讲解&#xff0c;同时对赛题背景以及完赛标准和要点进行了深入的剖析。会后更是设置问答环节&#xff0c;细…

Java高级特性 - IO流

第1关:什么是IO流 任务描述 本关任务:完成选择题。 相关知识 为了完成本关任务,你需要掌握: 1.什么是字节、字符; 2.什么是输入流、什么是输出流。 什么是字节 字节是指一小组相邻的二进制数码。通常是8位作为一个字节。它是构成信息的一个小单位,并作为一个整体来参…

力扣 leetcode 39. 组合总和

问题描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复被选取 。如果至少一个数…