element ui 下拉框分页(下拉框数据过多)

下拉框数据过多

Element UI中的下拉框是一个非常使用的组件。但是在实际开发中会遇到数据过多的问题。
最近的项目中需要使用下拉框来展示物料信息,但是物料信息有9000多条,最初是全部加载,但是会造成渲染特别的慢。后来采取的解决方式是后台每次返回30条数据,再通过远程搜索的方式获取需要的数据。采用远程搜索也存在一个问题,因为每次只显示30条,如果输入的关键字过短,你想要查找的值会不在这30条数据里,只能进一步的明确关键字。后来百度了一下,有个解决方案是在下拉框中实现分页,然后我自己也简单写了一个。

注:我是根据自己的业务写的,不会通用,而且会存在一些bug。如果有需要可以在此基础上自己再修改。

代码:

<template>
    <div>
        <el-select
            ref="selectRef"
            :disabled="disabled"
            :multiple="multiple"
            clearable
            filterable
            remote
            :remote-method="remoteSearch"
            placeholder="请选择"
            v-model.trim="selectValue"
            @change="handleChange"
            @visible-change="handleVisible"
            :loading="loading">
            <div class="option">
                <el-option
                    v-for="(item,index) in options"
                    :key="index"
                    :label="item.label"
                    :value="item.value">
                </el-option>
            </div>
            <div class="pagin" v-if="pageNumberAll>30">
                <el-pagination small background layout="prev, pager, next, total" :page-size="pageSize" :total="pageNumberAll" :current-page="pageNumber" @current-change="page"> </el-pagination>
            </div>
        </el-select>
    </div>
</template>

<script>

export default {
    components: {},
    props: {
        // 绑定的值(双向绑定显示的值)
        select: {
            type: [String,Array,Number],
            default: ''
        },
        // 是否多选
        multiple: {
            type: Boolean,
            default: false
        },
        // 请求地址
        url: {
            type: String,
            required: true
        },
        // 是否禁用
        disabled: {
            type: Boolean,
            default: false
        },
        // 模糊查询关键字
        filterKey: {
            type: String,
            default: ''
        },
        // 下拉修改时使用到的参数
        editinfo: {
            type: Object,
            default: () => {}
        },
        // 行下标唯一标识
        rowIndex: {
            type: Number,
            default: undefined
        },
        // 下拉显示的文字
        label: {
            type: String,
            default: ''
        },
        // 下拉选择的值
        value: {
            type: [String,Array,Number],
            default: ''
        }
    },
    data() {
        // 这里存放数据
        return {
            options: [],
            selectValue: '',
            pageNumber: 1,
            pageSize: 30,
            pageNumberAll: 0,
            loading: false
        };
    },
    mounted() {
        // 函数调用顺序要在options赋值为空数组之后
        this.initData();
        this.getOptionList();
    },
    // 方法集合
    methods: {
        // 处理值改变事件
        handleChange(value) {
            this.$emit('update:select',value);
            this.$emit('getStationType',this.rowIndex,this.tableData);
        },
        // 下拉框隐藏事件
        handleVisible(val) {
            // 下拉框隐藏后重新加载下拉数据
            console.log(this.$refs.selectRef.visible);
            if(!val) {
                this.getOptionList();
            }
        },
        // 过滤,实现模糊查询
        remoteSearch(value = '') {
            let params = {};
            let that = this;
            if(value) {
                params = {
                    queryConfig: [{
                        name: that.filterKey,
                        condition: 'like',
                        value: value
                    }]
                };
            }
            this.getOptionList(params);
        },
        // 获取列表数据
        getOptionList(query = {}) {
            this.loading = true;
            this.options = [];
            let that = this;
            let params = Object.assign({
                pageSize: 30,
                pageNumber: 1
            },query);
            this.$http.post(this.url,params)
                .then(({data: d}) => {
                    if(d.code == 0) {
                        this.pageNumberAll = d.data.total;
                        this.tableData = d.data.records;
                        d.data.records.forEach(item => {
                            that.options.push({
                                label: item[that.label],
                                value: item[that.value]
                            });
                        });
                        this.loading = false;
                    }
                });
            // 这里主要针对修改操作,如果当前下拉显示的值没有在下拉选项数组里(因为options数组里的值是会变化的)
            // 显示时会将value转换成字符串然后显示,所有将这条修改的数据添加到选项数组中
            if(this.editinfo && (JSON.stringify(this.editinfo)) != '{}') {
                this.options.push(this.editinfo);
            }
        },
        // 初始化数据
        initData() {
            // 当父组件上存在值时,对select值进行初始化
            this.selectValue = this.select;
        },
        // 主表格分页点击事件
        page(page) {
            this.pageNumber = page;
            this.getOptionList(); // 更新
        }
    }
};
</script>
<style lang="scss" scoped>
.option{
    min-height: 50px;
    height: auto;
    max-height: 150px;
    overflow-y: auto;
}
.pagin{
    background:#fff;
}
::-webkit-scrollbar{
    width: 2px;
}
</style>

使用

<template>
    <div>
        <ever-select v-else ref="searchSelect"  label="supplierName" value="id"  :select.sync="value" :url="unitUrl" filter-key="supplierName"></ever-select>
    </div>
</template>

<script>
export default {
    components: { },
    data() {
        return {
            url: this.$pdmService + 'material/materialDesc/pageList',
            value: ''
        };
    }
};
</script>

效果
请添加图片描述

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无知的小菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值