vue+element: use lazy loading or remote search when there is too much data in the El select drop-down box

Posted by MLJJ on Mon, 01 Nov 2021 18:42:41 +0100

Recently, a lot is too laggy to cause too much card or even stuck. Search lazy loading and remote search methods.

1. El select lazy loading

The data in the El select selector is returned through the back end. Nearly 20000 pieces of data are returned here. Click the selector page to open the special card, so it is best to use the lazy loading method. The specific use is as follows:

Control section:

<el-select
  v-model="form"
  placeholder=""
  v-el-select-loadmore="loadmore"	//Lazy loading method
>
  <el-option
    v-for="item in dataItems"
    :key="item.value"
    :label="item.label"
    :value="item.value"/>
</el-select>

Data part:

form: {},
allData: [],	//Store all data in the drop-down box
dataItems: [],	//Data displayed in the drop-down box
pageData: {		//Lazy loading related parameters, which means loading from the first data and loading 20 items at a time
  pageIndex: 1,
  pageSize: 20
},

Method part:

directives: {
  /** Drop down box lazy loading */
  'el-select-loadmore': {
    bind(el, binding) {
      const SELECTWRAP_DOM = el.querySelector(
        '.el-select-dropdown .el-select-dropdown__wrap'
      );
      SELECTWRAP_DOM.addEventListener('scroll', function() {
        const condition =
          this.scrollHeight - this.scrollTop <= this.clientHeight;
        if (condition) {
          binding.value();
        }
      });
    }
  }
},
methods: {
  /** Drop down box lazy loading */
  loadmore() {
    this.pageData.pageIndex++;
    this.getItems(this.pageData);	//Similar to paging query
  },
  /** Load 20 securities codes at a time */
   getItems(value) {
    let num = ~~this.pageData.pageIndex * ~~this.pageData.pageSize;
    this.dataItems = this.allData.filter((item, index, arr) => {
      return index < num;	//By default, allData has obtained data, so the method of obtaining allData data will not be put up
    });
  },
 }

This enables lazy loading of El select drop-down box data. Note:
If, like me, the options in the drop-down box (such as allData here) change dynamically, restore the data in pageData every time new data is obtained, that is, add these two sentences to the method of obtaining data:

this.pageData.pageIndex = 1;
this.pageData.pageSize = 20;

Otherwise, each time new data is obtained, it is only loaded from the place where it was loaded last time, instead of loading 20 pieces each time from the first one.

2. Drop down box options to search

Since there are nearly 20000 pieces of data in the drop-down box when I actually use it, it is impossible to load all the data and select again for demand reasons. Therefore, a search function is also required, as long as the following is added on the basis of the above code:

Control, El select is changed to:

<el-select
  v-model="form"
  placeholder=""
  filterable	//Indicates that the data is searchable
  :filter-method="dataFilter"	//Search method
  default-first-option		//Press enter in the input box and select the first matching item for use with filterable
  v-el-select-loadmore="loadmore"
>

In the method section, add the dataFilter method:

 /** Drop down box search */
  dataFilter(val) {
    if (val) { //val exists
      this.dataItems = this.allData.filter((item) => {
        if (!!~item.value.indexOf(val)) {	//The matching here is the value of the option, which can also be changed to label
          return true
        }
      })
    } else { //When val is empty, restore the array
      this.getItems(this.pageData);
    }
  },

3. Remote search

However, it is found that the above method is still a little stuck in the process of use, so I tried the remote search method again. At the beginning, I didn't show all the options, and the lazy load was removed. After entering the keyword, I matched the value value of the option to display the matching options:

Control, El select is changed to:

<el-select
  v-model="form"
  clearable
  filterable
  remote	//Represents a remote search
  :remote-method="remoteMethod"	//Remote search method
>

In the method section, add the remoteMethod method:

remoteMethod(query) {
  if (query !== '') {
    setTimeout(() => {
      this.dataItems = this.allData.filter(item => {
        return item.value.toLowerCase()	//Here is also the value of the matching option
          .indexOf(query.toLowerCase()) > -1;
      });
    }, 200);
  } else {
    this.dataItems = [];
  }
},

After trying, it is found that remote search will render faster than lazy load + direct search, so the final method is remote search

Topics: Vue element