美文网首页
ElementUI el-select 自定义下拉树

ElementUI el-select 自定义下拉树

作者: Cherry丶小丸子 | 来源:发表于2021-07-02 17:25 被阅读0次

    下拉树单选

    <el-select
        v-model="selectModel"
        placeholder="请选择..."
        size="small"
        clearable
        filterable
        :filter-method="singleTreeFilterMethod"
        ref="select"
        popper-class="customSelectPopper"
        @focus="singleTreeFocus">
        <el-option
            v-for="item of selectOptions"
            :key="item.id"
            :label="item.label"
            :value="item.id"
            v-show="false">
        </el-option>
        <div class="singleTree">
            <el-tree
                :data="selectTreeData"
                ref="selectTree"
                node-key="id"
                empty-text="无匹配数据"
                highlight-current
                :expand-on-click-node="expandOnClickNode" // 是否在点击节点的时候展开或者收缩节点
                :default-expanded-keys="defaultExpandedkeys" // 默认展开的节点的 key 的数组
                :props="{'label': 'label', children: 'children', disabled: 'disabled', isLeaf: 'isLeaf'}"
                :filter-node-method="filterNode"
                @node-click="selectTreeNodeClickEvent">
            </el-tree>
        </div>
    </el-select>
    
    data(){
        return {
            selectModel: '',
            selectOptions: [],
            selectTreeData: [{
                id: '1',
                label: '一级 1',
                isLeaf: false,
                children: [{
                    id: '1-1',
                    label: '二级 1-1',
                    isLeaf: false,
                    children: [{
                        id: '1-1-1',
                        label: '三级 1-1-1',
                        isLeaf: true
                    }]
                }]
            }, {
                id: '2',
                label: '一级 2',
                isLeaf: false,
                children: [{
                    id: '2-1',
                    label: '二级 2-1',
                    isLeaf: false,
                    children: [{
                        id: '2-1-1',
                        label: '三级 2-1-1',
                        isLeaf: true
                    }]
                }, {
                    id: '2-2',
                    label: '二级 2-2',
                    isLeaf: false,
                    children: [{
                        id: '2-2-1',
                        label: '三级 2-2-1',
                        isLeaf: true
                    }]
                }]
            }, {
                id: '3',
                label: '一级 3',
                isLeaf: false,
                children: [{
                    id: '3-1',
                    label: '二级 3-1',
                    isLeaf: false,
                    children: [{
                        id: '3-1-1',
                        label: '三级 3-1-1',
                        isLeaf: true
                    }]
                }, {
                    id: '3-2',
                    label: '二级 3-2',
                    isLeaf: false,
                    children: [{
                        id: '3-2-1',
                        label: '三级 3-2-1',
                        isLeaf: true
                    }]
                }]
            }],
            expandOnClickNode: false,
            defaultExpandedkeys: []
        }
    },
    methods:{
        /**
         * select单选下拉树自定义搜索
         * @param {Object} val
         */
        singleTreeFilterMethod(val){
            this.$refs.selectTree.filter(val);
        },
        /**
         * select获取焦点事件
         */
        singleTreeFocus(){
            this.$refs.selectTree.filter("");
        },
        /**
         * tree 节点过滤
         * @param {Object} value
         * @param {Object} data
         */
        filterNode(value, data) {
            if (!value) return true;
            return data.label.indexOf(value) !== -1;
        },
        /**
         * tree 节点点击事件
         * @param {Object} data
         */
        selectTreeNodeClickEvent(data){
            if(this.expandOnClickNode){ // 只有叶子节点可被选择
                if(data.isLeaf && data.isLeaf == true){
                    this.selectModel = data.id; // select v-model 赋值
                    this.selectOptions = [data]; // 隐藏的 select option 赋值
                    this.$refs.select.blur(); // 收起 select 下拉框
                }
            }else{ // 任意节点可被选择
                this.selectModel = data.id; // select v-model 赋值
                this.selectOptions = [data]; // 隐藏的 select option 赋值
                this.$refs.select.blur(); // 收起 select 下拉框
            }
        },
        /**
         * 回显数据
         */
        echoData(){
            let data = 请求接口返回值;
    
            // select v-model 赋值
            this.selectModel = data.id;
            // 隐藏的 select option 赋值
            this.selectOptions = [{
                id: data.id,
                label: data.label
            }];
    
            this.defaultExpandedkeys = [data.id]; // 展开选中的节点
            this.$refs.selectTree.setCurrentKey(data.id); // 设置节点高亮
    
            // 无法使用 current-node-key(当前选中的节点) 属性,如果在 data 里定义初始值,可以实现该 id 对应节点的默认选中高亮效果
            // 但如果用 this.currentNodeKey = xx 再修改这个值,没有任何变化
        }
    }
    

    下拉树多选

    <el-select
        v-model="selectModel"
        placeholder="请选择..."
        multiple
        size="small"
        ref="select"
        class="selectMultiple"
        popper-class="customSelectPopper"
        @remove-tag="removeTag">
        <el-option
            v-for="item of selectOptions"
            :key="item.id"
            :label="item.label"
            :value="item.id"
            v-show="false">
        </el-option>
        <div class="multipleTree">
            <!-- 当 el-select 在 el-form 表单中,并且属于必填项,添加 el-form-item 标签 以便解决 在搜索 input 中输入时执行 el-select 验证 -->
            <el-form-item style="margin-bottom: 0;" v-if="inForm">
                <el-input v-model="selectTreeNodeFilterText" size="small" placeholder="请输入关键字搜索" class="filterInp"></el-input>
            </el-form-item>
            <el-input v-else v-model="selectTreeNodeFilterText" size="small" placeholder="请输入关键字搜索" class="filterInp"></el-input>
            <div class="treeWrapper">
                <el-scrollbar class="commonScrollbar">
                    <el-tree
                        :data="selectTreeData"
                        show-checkbox
                        ref="selectTree"
                        node-key="id"
                        empty-text="无匹配数据"
                        :default-expanded-keys="defaultExpandedkeys" //  默认展开的节点的 key 的数组
                        :default-checked-keys="defaultCheckedKeys" // 默认勾选的节点的 key 的数组
                        :props="{'label': 'label', children: 'children', disabled: 'disabled', isLeaf: 'isLeaf'}"
                        :filter-node-method="filterNode"
                        @check="selectTreeNodeCheckEvent">
                    </el-tree>
                </el-scrollbar>
            </div>
        </div>
    </el-select>
    data(){
        return {
            inForm: false,
            selectModel: [],
            selectOptions: [],
            selectTreeData: [{
                id: '1',
                label: '一级 1',
                isLeaf: false,
                children: [{
                    id: '1-1',
                    label: '二级 1-1',
                    isLeaf: false,
                    children: [{
                        id: '1-1-1',
                        label: '三级 1-1-1',
                        isLeaf: true
                    }]
                }]
            }, {
                id: '2',
                label: '一级 2',
                isLeaf: false,
                children: [{
                    id: '2-1',
                    label: '二级 2-1',
                    isLeaf: false,
                    children: [{
                        id: '2-1-1',
                        label: '三级 2-1-1',
                        isLeaf: true
                    }]
                }, {
                    id: '2-2',
                    label: '二级 2-2',
                    isLeaf: false,
                    children: [{
                        id: '2-2-1',
                        label: '三级 2-2-1',
                        isLeaf: true
                    }]
                }]
            }, {
                id: '3',
                label: '一级 3',
                isLeaf: false,
                children: [{
                    id: '3-1',
                    label: '二级 3-1',
                    isLeaf: false,
                    children: [{
                        id: '3-1-1',
                        label: '三级 3-1-1',
                        isLeaf: true
                    }]
                }, {
                    id: '3-2',
                    label: '二级 3-2',
                    isLeaf: false,
                    children: [{
                        id: '3-2-1',
                        label: '三级 3-2-1',
                        isLeaf: true
                    }]
                }]
            }],
            defaultExpandedkeys: [],
            defaultCheckedKeys: [],
            selectTreeNodeFilterText: ''
        }
    },
    watch: {
        selectTreeNodeFilterText(val) {
            this.$refs.selectTree.filter(val);
        }
    },
    methods:{
        /**
         * tree 节点过滤
         * @param {Object} value
         * @param {Object} data
         */
        filterNode(value, data) {
            if (!value) return true;
            return data.label.indexOf(value) !== -1;
        },
        /**
         * tree 节点 check 事件(当复选框被点击的时候触发)
         * @param {Object} currentNodeObj 传递给 data 属性的数组中该节点所对应的对象
         * @param {Object} treeCheckNodeObj 树目前的选中状态对象
         */
        selectTreeNodeCheckEvent(currentNodeObj, treeCheckNodeObj){
            // 获取所有选中的节点 key 并给 select v-model 赋值
            this.selectModel = treeCheckNodeObj.checkedKeys;
            // 获取所有选中的节点对象 并给 隐藏的 select option 赋值
            this.selectOptions = treeCheckNodeObj.checkedNodes;
        },
        /**
         * 多选模式下移除 tag 事件
         * @param {Object} tag 当前 tag 对象
         */
        removeTag(data){
            // 获取所有选中的节点对象
            let checkNode = this.$refs.selectTree.getCheckedNodes(true);
    
            // 删除节点
            for(let i = 0; i < checkNode.length; i++){
                if(checkNode.id == data.id){
                    checkNode.splice(i, 1);
                    break;
                }
            }
    
            // 设置 tree 选中的节点
            this.$refs.selectTree.setCheckedNodes(checkNode);
        },
        /**
         * 回显数据
         */
        echoData(){
            let data = 请求接口返回值;
    
            // select v-model 赋值
            this.selectModel = data.ids;
            // 隐藏的 select option 赋值
            for(let i = 0; i < data.ids.length; i++){
                this.selectOptions.push({
                    id: data.ids[i],
                    label: data.label[i]
                });
            }
    
            this.defaultExpandedkeys = data.ids; // 展开选中的节点
    
            this.$refs.selectTree.setCheckedKeys(data.ids); // 默认选中的节点
            // 或者
            this.defaultCheckedKeys = data.ids; // 默认选中的节点
        }
    }
    

    css

    <style lang="scss" scoped>
        /* 自定义 select 下拉 公共样式 */
        .customSelectPopper{
            .el-scrollbar{
                display: block !important;
                .el-scrollbar__wrap{
                    max-height: 317px;
                    .el-scrollbar__view{
                        .el-select-dropdown__item{
                            display: none;
                        }
                        // 自定义下拉树-----单选
                        .singleTree{
                            .el-tree__empty-block{
                                padding: 4px 0;
                                font-size: 14px;
                                min-height: 14px;
                                height: 14px;
                                .el-tree__empty-text{
                                    color: #999;
                                }
                            }
                        }
                        // 自定义下拉树-----多选
                        .multipleTree{
                            .filterInp{
                                width: calc(100% - 40px);
                                display: block;
                                margin: 0 auto;
                            }
                            .treeWrapper{
                                padding: 10px 0;
                                height: 207px;
                                box-sizing: border-box;
                                .el-tree__empty-block{
                                    padding: 4px 0;
                                    font-size: 14px;
                                    min-height: 14px;
                                    height: 14px;
                                    .el-tree__empty-text{
                                        color: #999;
                                    }
                                }
                                .el-scrollbar{
                                    .el-scrollbar__bar{
                                        z-index: 2;
                                    }
                                }
                            }
                        }
                    }
                }
                &.is-empty{
                    .el-scrollbar__wrap{
                        .el-scrollbar__view{
                            padding: 6px 0;
                        }
                    }
                }
            }
            // 隐藏 select 空数据提示
            .el-select-dropdown__empty{
                display: none;
            }
        }
    
    
        /* 下拉多选 公共样式 */
        .selectMultiple{
            .el-select__tags{
                &>span{
                    display: block;
                    width: 100%;
                    overflow-x: auto;
                    overflow-y: hidden;
                    white-space: nowrap;
                    &::-webkit-scrollbar{
                        width: 0;
                        height: 0;
                    }
                }
            }
            &.noneClose{
                .el-select__tags{
                    .el-tag{
                        .el-tag__close{
                            display: none;
                        }
                    }
                }
            }
        }
    
        /* 全局设置el-scrollbar高度 */
        .commonScrollbar.el-scrollbar{
            height: 100%;
        }
        /* 全局隐藏el-scrollbar横向滚动条 */
        .commonScrollbar.el-scrollbar .el-scrollbar__wrap{
            overflow-x: hidden;
        }
        /* 全局设置子容器高度 */
        // .commonScrollbar.el-scrollbar .el-scrollbar__wrap .el-scrollbar__view{
        //    height: 100%;
        // }
    </style>
    

    相关文章

      网友评论

          本文标题:ElementUI el-select 自定义下拉树

          本文链接:https://www.haomeiwen.com/subject/vfloyltx.html