element-ui中select下拉框加载大数据渲染优化方式
作者:donggua_123
现在的前端项目中对于element-ui的使用几乎已经是一个常规动作了,但是组件库中的ui组件不一定都能满足实际场景的需求,比如今天要讲的select下拉框选择组件。
我们公司是做证券行业基础设施的,股票和证券的数量动不动就是上千,当使用select渲染的时候就会很有压力,我司大致3000条数据,全部渲染出来大致需要4s左右,并且多选模式时,选中和反选时会明显感觉卡顿,这在体验上是觉得不能接受的,所以就开始了优化历程。
方案一
把下拉多选功能做成弹框表格多选
可行性:表格设置selection属性,翻页功能可以解决大数据问题
实际情况:需要展示的字段只要2个即可,对于表格来说太少,显得太空;产品也不同意
弃之~~
方案二
利用select的远程搜索功能,初始化只加载指定数量数据,其它数据通过搜索功能查询
可行性:能满足大数据需求,只是体验上打了点折扣,后台也能支持
实际情况:产品能接受
暂时只想到了这两种方案,和后台商量了一下,具有可实施性,于是采用该方案。
方案分析
1.问题的根源是一次性渲染太多数据导致卡顿,那么第一次加载的数据就需要找到一个既能最大限度满足业务需求,又能无感加载的临界值,最终我选了300条
2.输入中文搜索时传递queryName作为模糊查询条件
3.如果通过搜索条件勾选了300条以后的数据,失去焦点,重新获取焦点时,需要将已勾选的数据放到300条数据的最前面,方便用户查看和反选,此时需要用已选择数据的id结合作为查询条件queryIds
4.编辑时后台只会返回新增时添加项对应的id集合,要正确显示对应的name值,需将id集合作为参数请求列表数据,如果不加参数默认返回前300条数据,如果id里有300之后的数据,则不会正确展示。第一次新增时无需传参。
基于以上分析,开始写代码
<!-- --> <template> <div class="container"> <el-select v-model="selectVal" filterable multiple clearable collapse-tags remote reserve-keyword :remote-method='remoteMethod' @focus="focus" > <el-option v-for="(item, index) in options" :key="index" :label='item.label' :value='item.id' > </el-option> </el-select> </div> </template>
<script> export default { data () { return { selectVal: [], options: [ // { // id: 1, // label: 'one' // }, // { // id: 1, // label: 'one' // } ] }; }, mounted() { this.getData() }, methods: { getData(queryName, queryIds) { this.$api('api/get', { 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) } } } } </script> <style lang='scss' scoped> </style>
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) } } }
这样就可以满足大数据加载的需求了
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
- 如何解决element-ui中select下拉框popper超出弹框问题
- 去除element-ui下拉框的下拉箭头的实现
- 基于element-ui中el-select下拉框选项过多的优化方案
- 关于element-ui select 下拉框位置错乱问题解决
- element-ui+vue-treeselect下拉框的校验过程
- 解决element-ui的下拉框有值却无法选中的情况
- Vue + Element-ui的下拉框el-select获取额外参数详解
- 在element-ui的select下拉框加上滚动加载
- 使用Vant完成DatetimePicker 日期的选择器操作
- 如何修改element-ui日期下拉框datetimePicker的背景色样式