现在的前端项目中对于element-ui的使用几乎已经是一个常规动作了,但是组件库中的ui组件不一定都能满足实际场景的需求,比如今天要讲的select下拉框选择组件。
我们公司是做证券行业基础设施的,股票和证券的数量动不动就是上千,当使用select渲染的时候就会很有压力,我司大致3000条数据,全部渲染出来大致需要4s左右,并且多选模式时,选中和反选时会明显感觉卡顿,这在体验上是觉得不能接受的,所以就开始了优化历程。
方案一:把下拉多选功能做成弹框表格多选
可行性:表格设置selection属性,翻页功能可以解决大数据问题
实际情况:需要展示的字段只要2个即可,对于表格来说太少,显得太空;产品也不同意
弃之~~
方案二:利用select的远程搜索功能,初始化只加载指定数量数据,其它数据通过搜索功能查询
可行性:能满足大数据需求,只是体验上打了点折扣,后台也能支持
实际情况:产品能接受
暂时只想到了这两种方案,和后台商量了一下,具有可实施性,于是采用该方案。
方案分析:
基于以上分析,开始写代码
focus函数是用来解决问题3或者编辑时获取焦点的,但是element-ui的select中点击选项时会触发focus方法,对比了正真的focus和点击,发现只有event.sourceCapabilities值可以区分,便用于区分这两个事件;如果有搜索条件时也不触发id搜索,只触发默认的remoteMethod即可
新增数据的时候已经可以用了,编辑的时候就会遇到问题4,此时需要用返回的id集合作为参数请求下拉数据,以正确展示已选数据
data () {
return {
selectVal: [],
options: [
// {
// id: 1,
// label: 'one'
// },
// {
// id: 1,
// label: 'one'
// }
],
type: 'edit'
};
},
mounted() {
this.initDialog()
},
methods: {
initDialog() {
this.getEditInfo(this.type).then(ids => {
this.selectVal = ids
this.getData(undefined, ids)
})
},
getEditInfo(type) {
return new Promise((resolve, reject) => {
if(type === 'edit') { // 编辑
this.$api('api/getInfo', {}).then(res => {
let ids = res.data
resolve(ids)
}).catch(err => {
// dosomething
})
}else {
resolve()
}
})
},
getData(queryName, queryIds) {
this.$api('api/getOptions', {
queryName: queryName || '',
queryIds: queryIds || '',
}).then(res => {
this.options = res.data
}).catch(err => {
// dosomething
})
},
remoteMethod(query) {
// 输入文字模糊搜索,覆盖旧数据
this.getData(query)
},
focus(event) {
if(!event.sourceCapabilities) return // 如果是勾选或反选下拉选项
if(!event.target.value) { // 输入框没有搜索条件时触发
this.getData(undefined, this.selectVal)
}
}
}
这样就可以满足大数据加载的需求了