小工具知识网

当前位置: 首页 > 行业知识 > Element树型下拉框/vue2树型下拉框/TreeSelect/树型下拉

行业知识

Element树型下拉框/vue2树型下拉框/TreeSelect/树型下拉

2026-11-13 18:24:43 来源:互联网转载

前言

        今天小谭要给大家分享的是基于element ui 的下拉框和树型控件二次分装的树型下拉框,element plus新增了这一组件,但是对于还在使用vue2的我来说,就很不友好。组件可以实现单选和多选,以及其他常用功能,废话不多说,直接上效果图:


代码实现

效果图如上,接下来实现代码:

使用时,如果想实现回显效果node-key必须要传!!!

HTMl:

                                                                                                                                                                                    {{ data[props.label] }}                                    ({{ data[props.children].length }})                                                                                                                                                

JS:

export default {    props: {        value: {            type: undefined,            default: null,        },        data: {            type: Array,            default: null,        },        props: {            type: Object,            default: null,        },    },    data() {        return {            defaultExpandedKeys: [],        };    },    created() {        this.propsInit();    },    mounted() {        setTimeout(this.initData, 10);    },    beforeUpdate() {        this.propsInit();        this.initData();    },    methods: {        initData() {            if (this.$attrs['show-checkbox'] === undefined) {                let newItem = this.recurrenceQuery(this.data, this.props.value, this.value);                if (newItem.length) {                    if (this.props.value && newItem[0][this.props.value]) {                        this.defaultExpandedKeys = [newItem[0][this.props.value]];                    }                    this.$nextTick(() => {                        this.$refs.myTree.setCurrentNode(newItem[0]);                    });                }            } else {                let newValue = JSON.parse(JSON.stringify(this.value));                if (!(newValue instanceof Array)) {                    newValue = [newValue];                }                if (newValue?.length) {                    let checkList = newValue.map(key => {                        if (key) {                            let newItem = this.recurrenceQuery(this.data, this.props.value, key);                            return newItem[0] || '';                        }                    });                    if (checkList?.length) {                        let defaultExpandedKeys = checkList.map(item => item?.[this.props.value || '']);                        if (defaultExpandedKeys.length) this.defaultExpandedKeys = defaultExpandedKeys;                        this.$nextTick(() => {                            this.$refs.myTree.setCheckedNodes(checkList);                        });                    }                }            }            this.$forceUpdate();        },        // 多选        handleCheckChange(data, e, ev) {            let checkList = this.$refs.myTree.getCheckedNodes();            let setList = null;            if (checkList.length) {                setList = checkList.map(item => item[this.props.value]);            }            this.$emit('input', setList);            // 共三个参数,依次为:传递给 data 属性的数组中该节点所对应的对象、节点本身是否被选中、节点的子树中是否有被选中的节点            this.$emit('change', data, e, ev);        },        // 单选事件        handleNodeClick(data, e) {            if (!(this.$attrs['select-last-node'] === undefined)) {                if (data[this.props.children] && data[this.props.children]?.length) {                    return false;                }            }            if (this.$attrs['show-checkbox'] === undefined) {                this.$emit('input', data[this.props.value]);                this.$refs.mySelect.blur();            }            this.$emit('change', data, e);        },        //   递归查找通用方法        recurrenceQuery(list, key, value) {            if (!list || !key || !value) return [];            let queryData = [];            list.map(item => {                if (item[this.props.children] && item[this.props.children].length) {                    queryData.push(...this.recurrenceQuery(item[this.props.children], key, value));                }                if (item[key] == value) {                    queryData.push(item);                }                return item;            });            return queryData;        },        selectChange(e) {            if (this.$attrs['show-checkbox'] !== undefined) {                let checkList = e.map(key => {                    let newItem = this.recurrenceQuery(this.data, this.props.label, key);                    return newItem[0] || '';                });                this.$refs.myTree.setCheckedNodes(checkList);                this.$emit('input', e);            }        },        selectClear(flag) {            if (this.$attrs['show-checkbox'] === undefined) {                if (!flag) this.$emit('input', '');                this.$refs.myTree.setCurrentKey(null);            } else {                if (!flag) this.$emit('input', []);                this.$refs.myTree.setCheckedKeys([]);            }            this.remoteMethod('');        },        getCheckedNodes() {            if (this.value !== null && this.value !== undefined && this.value !== '') {                return this.$refs.myTree.getCheckedNodes();            }            return [];        },        getCurrentNode() {            if (this.value !== null && this.value !== undefined && this.value !== '') {                return this.$refs.myTree.getCurrentNode();            }            return null;        },        valueFilter(val) {            if (this.$attrs['show-checkbox'] === undefined) {                let res = '';                [res] = this.recurrenceQuery(this.data, this.props.value, val);                return res?.[this.props.label] || '';            } else {                if (!val?.length) return [];                let res = val.map(item => {                    let [newItem] = this.recurrenceQuery(this.data, this.props.value, item);                    return newItem?.[this.props.label] || '';                });                if (!res?.length) return [];                res = res.filter(item => item);                return res;            }        },        propsInit() {            this.props.label = this.props.label || 'label';            this.props.value = this.props.value || 'value';            this.props.children = this.props.children || 'children';            if (this.$attrs['select-last-node'] !== undefined && !this.props.disabled) {                this.props.disabled = data => data?.[this.props.children]?.length;                this.$attrs['check-strictly'] = true;            }        },        remoteMethod(query) {            this.$refs.myTree.filter(query);        },        filterNode(value, data) {            if (!value) return true;            return data[this.props.label].indexOf(value) !== -1;        },    },    watch: {        value: {            deep: true,            handler(val) {                if (!val || !val?.length) {                    this.selectClear(true);                }            },        },    },};

CSS:

.selecTree {    max-height: 50vh;    overflow: auto;    padding: 5px;}.el-select {    width: 100%;}.slotSpan {    font-size: 14px;    b {        font-weight: normal;        font-size: 12px;        color: #999;    }}.selecTree ::v-deep .el-tree-node__content {    font-size: 14px;}

上一篇:基于爬虫+词云图+Kmeans聚类+LDA主题分析+社会网络语义分析对大唐不夜城用户评论进行分析

下一篇:SpringBoot整合knife4j(快速入门超详细版)