记录实现级联选择器多选功能时主要用到的函数

文章详细描述了级联选择器中的关键函数,如路径有效性验证、查找父级、获取全路径、状态判断以及初始化设置等,用于实现多选功能的完整逻辑。
摘要由CSDN通过智能技术生成

级联选择器多选功能时主要用到的函数

1、校验所给层级是否有效并且是否为完整路径

// 功能:涉及到级联选择器回显时,需校验是否为完整的路径,是则回显,不是则无无效路径
// options为级联数据,selectedPaths为要校验的数据
validatePaths(selectedPaths, options) {
    let {originKeys} = this;
    let current = options;
    for (const value of selectedPaths) {
        if (!current) return false;
        const node = current.find(item => item[originKeys.value] === value);
        if (node) {
            current = node.children;
        } else {
            return false;
        }
    }
    // 校验是否为完整路径
    return this.isChange ? true : !current || current.length === 0;
},

2、查找元素父级

// 使用场景:如果所有子节点状态变成已选择,那么要找到父级将其状态也变成已选择,应用于回显以及操作节点时使用
// value为操作值,arr为级联数据
findParentByValue(value, arr) {
    let {originKeys} = this;
    let parent = null;

    const findParent = (items, parentObj) => {
        for (const item of items) {
            if (item[originKeys.value] === value) {
                parent = parentObj;
                break;
            }
            if (item.children) {
                findParent(item.children, item);
            }
        }
    };

    findParent(arr, null);
    return parent;
},

3、获取所有级别的路径

getAllLevelsPath() {
    let str = '';
    let {originKeys} = this;

    this.activeAry.forEach((item, index) => {
        str +=
            index < this.activeAry.length - 1
                ? item.active[originKeys.label] + this.separator
                : item.active[originKeys.label];
    });

    return str;
},

4、状态判断

// 判断各个项状态,需要根据子项的状态判断父级也需要根据父级状态判断子集
allCheckStatus() {
    if (this.options.every(item => !this.getIsNotDisabled(item))) {
        return 'disabled'
    } else if (this.allCheckTrue(this.options)) {
        return 'checked'
    } else if (this.hasCheckTrue(this.options)) {
        return 'indeterminate'
    } else {
        return 'unChecked'
    }
},
// 元素没有被禁用则返回true
getIsNotDisabled(item) {
    let {defaultDisabledItems, originKeys} = this;
    if (!this.isChange) {
        if (defaultDisabledItems.includes(item[originKeys.value])) {
            return false;
        }
        if (item.children && item.children.length > 0) {
            return item.children.some(child => this.getIsNotDisabled(child));
        }

        return true;
    } else {
        return !defaultDisabledItems.includes(item[originKeys.value])
    }
},
// 多选级联每一项元素的勾选状态
getCheckStatus(item) {
    if (!this.isChange) {
        if (!this.getIsNotDisabled(item)) {
            return 'disabled'
        } else if (!item.check &&
            (!item.children || !item.children.length || !this.hasCheckTrue(item.children))
        ) {
            return 'unChecked'
        } else if (!item.children || !item.children.length || this.allCheckTrue(item.children)) {
            return 'checked'
        } else {
            return 'indeterminate'
        }
    } else {
        return !this.getIsNotDisabled(item) ? 'disabled' : item.check ? 'checked' : 'unChecked'
    }
},
// 所有元素是否都被选择,包括孩子元素,剔除禁选元素
allCheckTrue(arr) {
    return arr.every(
        item => (item.check || !this.getIsNotDisabled(item)) &&
            (!item.children || !item.children.length || this.allCheckTrue(item.children)))
},
// 判断孩子元素中是否有被选择的,剔除禁选元素
hasCheckTrue(arr) {
    return arr.some(item => item.check &&
        this.getIsNotDisabled(item) ||
        (item.children && this.hasCheckTrue(item.children))
    );
},

5、给初始化的数组增加check属性

addCheckProperty(arr, ids, flag) {
    let {originKeys} = this;
    for (const item of arr) {
        if (ids.includes(item[originKeys.value])) {
            this.$set(item, 'check', flag);
            this.updataSelectedItems(item, flag)
        }
        if (item.children && item.children.length) {
            this.addCheckProperty(item.children, ids, flag);
        }
    }
},

6、元素没有被禁用则返回true

// 判断元素有没有被禁用,涉及父级全选以及回显功能
getIsNotDisabled(item) {
    let {defaultDisabledKeys, originKeys} = this;
    if (!this.isChange) {
        if (defaultDisabledKeys.includes(item[originKeys.value])) {
            return false;
        }
        if (item.children && item.children.length > 0) {
            return item.children.some(child => this.getIsNotDisabled(child));
        }

        return true;
    } else {
        return !defaultDisabledKeys.includes(item[originKeys.value])
    }
},

7、更新某一项

updataSelectedItems(item, flag) {
    let {originKeys} = this;
    this.$set(item, 'check', flag);

    if (item.children && item.children.length && !this.isChange){
        this.changeCheckProperty(item.children, flag);
    } else {
        if (flag) {
            // 未被禁选&&没有被选择的元素push到selectedItems
            this.getIsNotDisabled(item) &&
            !this.selectedItems.find(selectedItem => selectedItem[originKeys.value] === item.value) &&
            this.selectedItems.push(item)
        } else {
            // 过滤掉取消勾选的元素
            this.selectedItems = this.selectedItems.filter(
                val => val[originKeys.value] !== item[originKeys.value]
            )
        }
        // 拿到全路径
        if (this.isShowLevels) {
            let hierarchyArr = [];
            let selectedOptionsArr = []
            this.selectedItems.forEach(item => {
                hierarchyArr.push(
                    this.getSelectedOptionsWithPath(item[originKeys.value], this.options).hierarchy
                )
                selectedOptionsArr.push(
                    this.getSelectedOptionsWithPath(item[originKeys.value], this.options).selectedOptions
                )
            })
            this.selectedItemsAllPath = hierarchyArr
            this.activeItems = selectedOptionsArr
        }
    }
},

8、返回点击事件回传参数 以及全路径

//事件回传参数处理
getSelectedOptionsWithPath(val, options) {
    let {originKeys, separator} = this;
    let hierarchy = null;
    let selectedOptions = [];

    const findOption = (items, parentHierarchy) => {
        for (const item of items) {
            if (item[originKeys.value] === val) {
                let obj = {}
                obj[originKeys.value] = item[originKeys.value]
                obj[originKeys.label] = item[originKeys.label]
                selectedOptions.push(obj);
                hierarchy = parentHierarchy ?
                    `${parentHierarchy}${separator}${item[originKeys.label]}` :
                    item[originKeys.label];
                return true;
            }
            if (item.children && item.children.length) {
                const currentHierarchy = parentHierarchy ?
                    `${parentHierarchy}${separator}${item[originKeys.label]}` :
                    item[originKeys.label];
                const found = findOption(item.children, currentHierarchy);
                if (found) {
                    let obj = {}
                    obj[originKeys.value] = item[originKeys.value]
                    obj[originKeys.label] = item[originKeys.label]
                    selectedOptions.unshift(obj);
                    return true;
                }
            }
        }
        return false;
    };

    findOption(options, null);

    return {hierarchy, selectedOptions};
},
  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值