el-select 性能优化

目录

1.目的

2.原理

3.优点

4.源码

1)安装插件

2) 创建全局组件VirtualListSelect。

a.简单页面也即正常开发的页面中

b.通过表单配置在页面中渲染出来的下拉框


1.目的

为了解决 element-ui 中 el-select 组件在大数据量的情况下出现的性能问题(数据量太大,导致渲染过慢,或造成页面卡顿甚至于卡死) 。

2.原理

模拟虚拟滚动,对 el-select组件结合vue-virtual-scroll-list(vue虚拟列表)插件进行二次封装

3.优点

适用于只查询一次接口,后端一次性把数据返回。 对比其他的优化方案,有以下优点

方案一:后台进行分页;这种。。嗯,那后端人员可能不乐意了,心里想我都把数据返回给你了,加载慢,页面卡顿不应该你前端的问题吗(关我什么事)。ok,为了避免这种情况,我们就不麻烦后端同学在每个下拉框数据返回后进行分页了,那可是个大工程。对比这种方案优点就是

  • 无需后端进行配合,只需要初始化的时候一次性把数据返回给前端即可

方案二:前端懒加载,这种确实可以,我不用此方案就是考虑到数据量过大,那即使页面初始加载的时候较快,但是在页面销毁,简单来说就是切页面的时候,你要销毁所有的dom节点那肯定会出现你的路由已经变化了,但是你的页面还没跳转,造成用户体验不好。对比这种方案我的方案优点

  • 由于不管下拉框如何下拉,至始至终都只渲染自己设置的规定的数量,比如:keeps="20"那这个下拉框始终只会渲染20条下拉数据,vue种dom节点那就渲染20条,对比成千上万,不论是初始化或者销毁速度都会明显的提升,用户体验好。

4.源码

1)安装插件

由于需要使用插件vue-virtual-scroll-list,所以我们先在项目中把插件安装一下;

插件官网地址:vue-virtual-scroll-list - npmvue-virtual-scroll-list - npmvue-virtual-scroll-list - npm

npm install vue-virtual-scroll-list --save

2) 创建全局组件VirtualListSelect。

我使用的环境相对来说比较复杂 ,因为我封装的这个组件主要用在低代码平台中,即下拉框是通过页面配置然后渲染出来的,所以需要接收许多参数,但是在正常开发的页面中不需要接收这么多参数,为了方便读者借鉴,我就两种都记录一下。正常开发的页面已经满足大部分读者的需求。

a.简单页面也即正常开发的页面中

  •  在src/components下创建VirtualListSelect文件夹,文件夹下大概格式如下:

el-select 性能优化_第1张图片

  •  VirtualListSelect.vue文件




  •  itemComponent.vue 文件




组件封装完成后,我们最好将其注册成全局组件,以便在系统中使用

import VirtualListSelect from './VirtualListSelect';

Vue.component('virtual-list-select', VirtualListSelect);

  • 下面写一个简单的demo 

demo.vue




b.通过表单配置(低代码平台)在页面中渲染出来的下拉框

  • VirtualListSelect.vue



  •  Readme.md文件
## VirtualListSelect

### 1. 组件说明
* 本组件是对 el-select组件结合vue-virtual-scroll-list(vue虚拟列表)插件的二次封装。原理:模拟虚拟滚动,目的是为了解决 element-ui 中 el-select 组件在大数据量的情况下出现的性能问题(数据量太大,导致渲染过慢,造成页面卡顿甚至于卡死)。
* 插件地址:https://www.npmjs.com/package/vue-virtual-scroll-list
### 2. 实现原理
* 用vue-virtual-scroll-list这个插件去包裹需要循坏展示的标签。这里就是el-option标签。
* 由于插件的 data-component 属性,需要抽离出el-option标签封装成一个组件
### 3. 属性说明
* data-key=“‘id’” 就是绑定的唯一key值
* data-sources=“selectArr” 下拉框的数组
* data-component=“itemComponent” 就是抽离中的el-option组件
* keeps=“20” 渲染的个数(默认30个)
* extra-props 值为对象,可以传入自定义属性进去
### 4. 方法
* 实现模糊搜索功能,使用el-select自带的filterMethod方法
* visible-change事件实现下拉框出现/隐藏时触发虚拟列表重置和把列表重置成全量数据
### 5. 注意点
1. 
  •  低代码中render函数

render.js

export default {
  name: 'render',
  props: {
    type: String,
    config: Object
  },
  render: function(h) {
    switch (this.type) {
      case 'select':
        // return selectItem(h, this.config);
        return virtualListSelect(h, this.config);
      default:
        return '';
    }
  }
};

// 虚拟下拉列表
function virtualListSelect(h, config) {
  const {
    model,
    key,
    props,
    listeners,
    options,
    optionConfig,
    placeholder,
    syncConfig,
    goods,
    value,
    multiple
  } = config;
  let opl = 'label';
  let opv = 'value';

  if (optionConfig) {
    if (optionConfig.label) {
      opl = optionConfig.label;
    }
    if (optionConfig.value) {
      opv = optionConfig.value;
    }
  }

  const opts = options;

  const on = listeners || {};
  let pps = props || {};
  if (syncConfig) {
    pps = {
      ...pps,
      ...syncConfig()
    };
  }
  return h('virtual-list-select', {
    props: {
      placeholder: placeholder || '请选择',
      filterable: true,
      ...pps,
      value: value,
      selectData: {
        data: opts, // 下拉框数据
        label: opl || 'text', // 下拉框需要显示的名称
        value: opv, // 下拉框绑定的值
        isRight: false //右侧是否显示
      },
      multiple,
      allowCreate: goods.allowCreate,
      disabled: goods.readable === 1 || goods.pageDisabled,
      'multiple-limit': goods.itemMultipleLimit,
      'collapse-tags': true,
      clearable: goods.clearAble,
      'popper-append-to-body': false
    },
    on: {
      ...on,
      change: (val) => {
        goods.value = val;
        if (model) {
          model[key] = val;
        }
        if (on.change) {
          on.change(val);
        }
      }
    }
  });
}

你可能感兴趣的:(vue专栏,elementUI,vue.js,elementui,前端)