开局一张图,内容全靠编。大家好!我是:记得清缓存。 写这篇文章主要是立了个flag,如果有不足之处,请各位大佬多多指教。话不多说,进入正题。
问题描述
我正在使用vue+element技术栈开发后台管理系统。开发时遇到一个问题:el-select数据过多导致页面卡顿。
解决思路
造成卡顿的原因都知道了,那就对症下药:把el-options的数据减少。封装另一个自己的select ==> MyElSelect
过程
- 先把所有的optionsList传入,并取前50条。
MyElSelect.vue
props: {
allList: {
type: Array,
default: () => []
}
}
mounted () {
this.options = this.allList.slice(0, 50);
},
- 由于我们只取了前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)。