elementUI懒加载树组件el-cascader无法回填问题

一、使用方法及源吗

使用方法

// postInfo为每层下钻岗位的id    selectedName为XXX岗位名称,也就是最后需要显示的岗位信息     url为获取岗位信息的url
// postInfo: [111,222,333], selectedName: '皮草运营商', url: "xxx.findxxx"

<origanizeCascader v-model="postInfo" :selected-name.sync="selectedName" url="xxx.findxxx"/>

源代码origanize-cascader.vue

<template>
    <el-cascader
        v-model="checkedValue"
        :options="options"
        :props="config"
        :show-all-levels="false"
        ref="cascader"
        popper-class="sc-cascader-popper cascader-popper"
    />
</template>

<script>
export default {
    props: {
        value: {
            type: Array,
            default: () => []
        },
        selectedName: {
            type: String,
            default: ''
        },
        url: {
            type: String,
            default: 'xxx'
        }
    },
    data() {
        return {
            checkedValue: [],
            options: [],
            config: {
                label: 'dimName',
                value: 'pId',
                leaf: 'hasChild',
                checkStrictly: true,
                lazy: true,
                lazyLoad: this.lazyLoad
            },
            inited: false,
            hadIds: []
        };
    },
    watch: {
        '$store.state.user': {
            handler(newVal) {
                if (!newVal || !newVal.postList || !newVal.postList.pId) {
                    return;
                }
                this.initOptions(newVal.postList.pId).then(() => {
                    this.checkedHad(this.options);
                });
            }
        },
        checkedValue: {
            deep: true,
            handler(newVal) {
                if (
                    newVal.length === this.value.length
                    && this.value.every(v => newVal.includes(+v))
                ) {
                    return;
                }
                this.$emit('input', newVal);
            }
        },
        value: {
            deep: true,
            handler(newVal) {
                if (!this.inited) {
                    return;
                }
                if (
                    newVal.length === this.checkedValue.length
                    && newVal.every(v => this.checkedValue.includes(+v))
                ) {
                    return;
                }
                this.setCheckedValue();
            }
        },
        selectedName(newVal) {
            if (newVal) {
                this.$refs.cascader.inputValue = newVal;
            }
        }
    },
    mounted() {
        this.$refs.cascader.$refs.panel.$watch('menus', {
            handler(newVal) {
                const len = newVal.length;
                if (!newVal[len - 1].length) {
                    this.menus.splice(len - 1, 1);
                }
            }
        });
        this.$refs.cascader.$watch('inputValue', {
            immediate: true,
            handler: newVal => {
                if (newVal && newVal !== this.selectedName) {
                    this.$emit('update:selectedName', newVal);
                }
            }
        })
    },
    methods: {
        lazyLoad(node, resolve) {
            if (node.isLeaf || node.root || this.hadIds.includes(node.value)) {
                return resolve();
            }
            this.getChildren(node.value)
                .then(res => {
                    resolve(res);
                });
        },
        getChildren(pId) {
            return this.$axios
                    .post(this.url, {
                        pId
                    }).then(res => {
                        if (res.data === '') {
                            this.$alert('无权限,请联系管理员');
                            this.$trigger('setLoading', false);
                            return;
                        }
                        return res.data.dataList;
                    }).catch(error => {
                        this.$alert(error.msg || "获取下辖岗位失败,请稍后重试", "错误提示");
                    });
        },
        initOptions(pId) {
            return this.getChildren(pId)
                        .then(res => {
                        if (res[0].pId === pId) {
                            this.options = res;
                        }
                        else {
                            const {pName, pId} =  this.$store.state.user.postList;
                            this.options = [{
                                dimName: pName,
                                pId,
                                hasChild: false,
                                children: res
                            }];
                        }
                    })
                    .finally(() => {
                        this.inited = true;
                        this.setCheckedValue();
                    })
        },
        checkedHad(arr) {
            arr.forEach(v => {
                if (v.children && v.children.length) {
                    this.hadIds.push(+v.pId);
                    this.checkedHad(v.children);
                }
            })
        },
        setCheckedValue() {
            if (this.value.length < 3) {
                this.checkedValue = this.value.map(v => +v);
            }
            else {
                const arr = this.value.slice(1, this.value.length - 1);
                Promise
                    .all(arr.map(v => this.getChildren(v)))
                    .then(res => {
                        this.handlerOption(res);
                        this.checkedValue = this.value.map(v => +v);
                    });
            }
        },
        handlerOption(res) {
            const len = res.length;
            const needSetChildrenOption = this.options[0].children.find(v => +v.pId === +this.value[1]);

            for(let i = 0; i < len - 1; i++) {
                const item = res[i].find(v => +v.pId === +this.value[i + 2]);
                item.children = res[i + 1];
            }

            
            this.$set(needSetChildrenOption, 'children', res[0]);
            this.checkedHad(this.options);
            this.hadIds = [...new Set(this.hadIds)];
        }
    }
};
</script>

<style lang="less">
.sc-cascader-popper {
    max-width: 70%;
    min-width: 100px;
    overflow-x: auto;
    .el-cascader-panel {
        .el-cascader-menu__wrap {
            height: 100% !important;
        }
        .el-scrollbar__wrap {
            overflow-y: auto;
            overflow-x: hidden;
            margin-bottom: 0 !important;
            margin-right: 0 !important;
        }
        .el-cascader-menu {
            flex-shrink: 0;
        }
    }
}
</style>

二、效果展示

默认
在这里插入图片描述
展开:
在这里插入图片描述

三、源码解析

流程:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值