开发中会遇见超大数据量的筛选功能,而且后端接口是一股脑全部扔给前端,前端虽然有elementUi等的组件自带搜索功能,可是大数据量的筛选和dom创建会让页面异常卡顿。
1、筛选框需要一次展示那么多数据吗?
很显然是不需要的,一般的筛选框是给用户做选择用的,用户不会费力的使劲找,一般数据量大的筛选用户都会有目的的精确筛选,默认筛选给一个示例就行了
2、怎么做?
- 获取筛选框所有数据
- 截取50个左右的默认数据
- 输入搜索时候从全数据中检索并截取50个赋值给筛选框
示例代码(以iviewUI为例)
<template>
<Select
:value="value"
:placeholder="placeholder"
:default-label="defaultLabel" class="select-width" clearable filterable
:remote-method="remoteFilter"
:style="{width:width+'px'}"
@on-change="change"
@on-query-change="selectInput">
<Option v-for="(val,k) in options" :key="k" :value="val[optionValue]" :disabled="!!val.disabled">{{ val[optionLabel] }}</Option>
</Select>
</template>
/**
* 快速搜索组件
* 传入源数据后,前端做搜索
**/
export default {
props: {
value: { // model
type: [Number,String],
default: ''
},
list: { // 原数据
type: Array
},
optionValue: { // value
type: String,
default: 'value'
},
optionLabel: { // label
type: String,
default: 'label'
},
preOptions:{ // 预览展示的插入值
type: Array,
default:function() {
return []
}
},
placeholder: {
type: String,
default: '请选择或者搜索'
},
width:{ // 筛选框的宽度
type:Number,
default: 180
},
preNum: { // 展示个数
type:Number,
default: 66
}
},
data() {
return {
options: [],
defaultLabel:''
}
},
mounted() {
this.setDefaultLabel(this.value)
this.remoteFilter(this.defaultLabel)
},
methods: {
// 远端搜
remoteFilter(query){
if (query !== '') {
let options = []
this.list.forEach((e,i) => {
e.showName.includes(query) && options.push(e)
})
options && options.length && (this.options = [...this.preOptions,...options])
} else {
let options = this.list.slice(0,this.preNum)
this.options = [...this.preOptions,...options]
}
},
// default-label
setDefaultLabel(val){
let O = this.list.find(e => e.name === val)
O && (this.defaultLabel = O.showName || '')
},
// 清空后赋值默认
selectInput(query){
if(query === ''){
let options = this.list.slice(0,this.preNum)
this.options = [...this.preOptions,...options]
}
},
// 选中
change(e){
this.$emit('on-change',e)
}
}
}
</script>