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>
  
Logo

前往低代码交流专区

更多推荐