浅谈ElementUIel-select数据过多解决办法
⽬录
1. 场景描述
2.解决办法
el-select组件的options条数过多时的解决⽅案
业务场景
解决思路
注意事项
1. 场景描述
不知道你有没有这样的经历,下拉框的选项很多,上万个选项甚⾄更多,这个时候如果全部把数据放到下拉框中渲染出来,浏览器会卡死,体验会特别不好
⽤⼈会说element-ui的select有⼀个remote-method,⽀持远程搜索,我们让服务端⽀持⼀下不就可以了,当然这是⼀种解决的⽅案。但是有时候这种⽅法有时候不⼀定适⽤
(1)有时候服务端数据是经过计算返回给我们的,可能返回不是特别快,体验不是很好
(2)有时候数据可能只有⼏千条,全部渲染⼜不太合适,⼀直掉接⼝不是特别好
(3)仅仅通过前端能不能解决,如果能解决,岂不是减轻了服务端的⼯作和压⼒
2.解决办法
1 ) 分段加载:也不加载下拉项,通过点击下拉框的时候,再去加载,此时的选项全部加载进来,该种情况只适⽤于缓加载情况,需要点击加载完后才能下拉选项,体验⼀般。
2 )提⽰:element-ui的select有⼀个filter-method⽅法,我们可以通过这个⽅法来进⾏过滤下拉项
假设我们有个下拉框是⽤来选择⽤户的
<el-select
v-model="userId"
filterable
:filter-method="userFilter"
clearable>
<el-option
v-for="item in userList"
:key="item.userId"
:label="item.username"
:value="item.userId"
></el-option>
</el-select>
userFilter(query = '') {
let arr = this.allUserList.filter((item) => {
return item.username.includes(query) || item.userId.includes(query)
})
if (arr.length > 50) {
this.userList = arr.slice(0, 50)
} else {
this.userList = arr
}
},
getUserWhiteList() {
HttpRequest.post("/api/admin/community/getUserWhiteList").then(
response => {
this.allUserList = response.data.list;
this.userFilter()
}
);
},
如上所⽰,我们从后台获取⽤户列表,经过我们⾃⼰的过滤,我们每次只渲染50条数据,⽆论有多少数据,对我们来说也⽀持⼀个变量,占个内存。当然数据越多,数组的遍历也会相应的慢,但是这个影响不⼤。
我们不仅能过滤名字,还可以对我们制定的任⼀项进⾏过滤
优化:上⾯的代码我们还可以适当优化下,只有发现了数组长度超过了50项,我们就停⽌遍历
el-select组件的options条数过多时的解决⽅案
业务场景
当使⽤el-select组件时,如果options数量过多,会存在的弊端:
页⾯渲染出⼤量el-option节点,会导致页⾯卡顿甚⾄卡死,⽤户体验极差。
选择时条⽬众多,查困难。
本次我遇到的场景是options数量为6-9千的情况。
解决思路
从总options中取出固定条⽬的⼩option(renderOption)⽤于页⾯渲染,利⽤el-select提供的filter-method⽅法进⾏搜索过滤,在搜索时⽤过滤结果更新renderOption。
代码实现
下⾯是vue的组件封装
<template>
<el-select
class="yt-select"
v-model="currValue"
filterable
v-bind="$attrs"
:filter-method="userFilter"
vue element admin:disabled="disabled"
:clearable="clearable"
@change="change"
>
<el-option
v-for="option in renderOption"
:
key="option.value"
:value="option.value"
:label="option.label"
>{{ option.label }}</el-option>
</el-select>
</template>
<script>
export default {
name: 'easy-select',
props: {
value: {
type: [String, Number],
default: ''
},
max: {
type: Number,
default: 30
},
disabled: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
},
options: {
type: Array,
default: () => []
}
},
data () {
return {
renderOption: []
}
},
computed: {
currValue: {
get () {
return this.value || ''
},
set (value) {
this.$emit('input', value)
}
}
},
watch: {
value () {
this.addValueOptions()
},
options: {
handler (V) {
this.init()
},
deep: true
}
},
created () {
this.init()
},
methods: {
async init () {
this.userFilter()
this.addValueOptions()
},
addValueOptions () {
if (this.currValue) {
let target = this.options.find((item) => { // 从⼤option中到当前条
return item.value === this.currValue
})
if (target) { // 将当前条与⼩option⽐对,没有则加⼊
if (derOption.every(item => item.value !== target.value)) {
}
}
}
},
addFilterOptions (label) {
// 每次查输⼊时,若有精确匹配的条⽬,保证该条⽬⼀定在renderOption内
let target = this.options.find((item) => { // 从⼤option中到当前条
return item.label === label
})
if (target) { // 将当前条与⼩option⽐对,没有则加⼊
if (derOption.every(item => item.label !== target.label)) {
}
}
},
userFilter (query = '') {
let arr = this.options.filter((item) => {
return item.label.includes(query) || item.value.includes(query)
})
if (arr.length > this.max) {
this.addFilterOptions(query)
} else {
}
},
change (value) {
this.$emit('change', value)
if (!value) { // 单选清空-optons初始化下
this.userFilter()
}
}
}
}
</script>
注意事项
初始化和value值变化时,需要到value对应具体项,并加⼊renderOptions
搜索时,可能过滤到的n条数据都没有包含⽤户想的具体项,因此,过滤时需要进⾏⼀下精确查,将匹配项放⼊renderOptions头部
到此这篇关于ElementUI el-select 数据过多解决办法的⽂章就介绍到这了,更多相关ElementUI el-select 数据过多内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论