工作上的小问题:解决el-select数据过多卡顿、回显。

4,116 阅读1分钟

开局一张图,内容全靠编。大家好!我是:记得清缓存。 写这篇文章主要是立了个flag,如果有不足之处,请各位大佬多多指教。话不多说,进入正题。

问题描述

我正在使用vue+element技术栈开发后台管理系统。开发时遇到一个问题:el-select数据过多导致页面卡顿

解决思路

造成卡顿的原因都知道了,那就对症下药:把el-options的数据减少。封装另一个自己的select ==> MyElSelect

过程

  1. 先把所有的optionsList传入,并取前50条。
MyElSelect.vue
props: {
    allList: {
        type: Array,
        default: () => []
    }
}

 mounted () {
    this.options = this.allList.slice(0, 50);
},
  1. 由于我们只取了前50条,所以我们需要自定义搜索的方法。
<template>
    <el-select 
    v-model="selectValue" 
    v-bind="customizedAttrs" 
    v-on="$listeners"
    @change="handleChange"
    :filter-method="handleFilter">
        <el-option
            v-for="item in options"
            :key="item[optionValue]"
            :label="item[optionLabel]"
            :value="item[optionValue]">
        </el-option>
    </el-select>
</template>

<script>
export default {
    name: 'MyElSelect',
    inheritAttrs: false,
    props: {
        allList: {
            type: Array,
            default: () => []
        },
        // options 里面的key对应的值
        optionValue: {
            type: String,
            default: 'id'
        },
        // options 里面的label对应的值
        optionLabel: {
            type: String,
            default: 'name'
        }
    },
    data () {
        return {
            options: [],
            selectValue: ''
        }
    },
    computed: {
        customizedAttrs() {
            return {
                ...this.$attrs,
            };
        },
    },
    methods: {
        handleFilter (val) {
            let options = this.allList.filter((item) => {
                return item[this.optionLabel].includes(val)
            });
            // 还是老样子取前五十条
            this.options = options.slice(0, 50);
        }
    }
}
</script>

为了用起来和el-select一样我学习了这位老哥写的透传: juejin.cn/post/693968… 到这里已经可以搜索了、不卡了,只剩解决最后一个回显的问题了

3.使用v-model 这里我还是想在我都组件上使用v-model <My-El-Select v-model="parentSelectValue"></My-El-Select> 所以在MyElSelect.vue加上change方法

handleChange (val) {
    this.$emit("input", val);
},

4.解决回显 v-model上绑定的值可以在this.$attrs.value得到所以写了个方法:

mounted () {
    this.initData();
},
initData () {
    let options = [];
    if (this.$attrs.value) {
        // 有值
        this.selectValue = this.$attrs.value;
        let index = -1;
        let targetItem = {};
        // 找到绑定的value的item
        for (let i = 0; i < this.allList.length; i++) {
            let item = this.allList[i];
            if (item[this.optionValue] == this.$attrs.value) {
                index = i;
                targetItem = item;
                break;
            }
        }
        if (index != -1) {
            // 找到了
            if (index < 50) {
                // 五十条内
                options = this.allList.slice(0, 50);
            } else {
                // 五十条外
                options = this.allList.slice(0, 50);
                options.unshift(targetItem);
            }
        } else {
            // 没找到 自己好好想想为啥没找到(狗头保命.gif)
            this.selectValue = '';
            options = this.allList.slice(0, 50);
        }
    } else {
        options = this.allList.slice(0, 50);
    }
    this.options = options;
    // console.log(this.options)
},

使用

我还不想每个页面都引用所以我在main.js里面注册了全局组件。

import MyElSelect from '@/components/Form/MyElSelect';
Vue.component("MyElSelect", MyElSelect);

最终使用:

<My-El-Select 
    v-model="form.wharfId" 
    :allList="wharfList"
    placeholder="请选择码头"
    filterable class="hundredPercent" 
    size="small">
</My-El-Select>

结语

如果对你有帮助,请来个赞。如果对你没帮助,来都来了赞一个。有啥写的不好的,指出来我肯定改(菜鸡瑟瑟发抖.png)。