Vue中自定义指令 解决el-select组件下拉选项过多导致页面卡顿问题

7/21/2022

# 问题及起因

饿了么UI的 el-select 组件, 如果开启了远程搜索功能, 若查询到的数据量太大控制台会报警告 [Vue warn] : Error in rander : "RangeError : Maximun call stack size exceeded" ,大致意思就是超过最大调用堆栈大小, 所以 el-select 组件不能正常展示接口返回的数据, 页面也会长时间卡顿

# 解决办法及思路:

自定义一个监听 el-select下拉触底的指令, 当监听到 el-select 组件滚动到底部时, 触发懒加载方法loadMore( ) ,此方法会追加 n 条数据到滚动到底部前已展示的数组中, 这样就避免了一次性渲染所有请求到的数据

# 自定义指令

// utils/directive.js
import Vue from "vue"
Vue.directive(
  'el-select-loadmore', {
    bind(el, binding) {
      //拿到要展示的scroll节点
      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()
      })
    }
  }
)

// main.js中引入
import "./utils/directive.js"

# 组件中使用

<el-select
    filterable
    remote
    remote-method="getOptionsData"
    v-el-select-loadmore="loadMore">
    <el-option
       v-for="item in selectOptions.slice(0,rangeNumber)"
       :key="item.id"
       :label="item.name"
       :value="item.id">
    </el-option>
</el-select>
data(){
    return {
        selectOptions:[], //远程搜索接口返回的数据
        rangeNumber:20   //下拉框初始展示的选项数
    }
},
methods:{
    //追加数据项的方法
    loadMore(){
       return () => this.rangeNumber += 5 //每次滚动到底部新增条数 n 自定义
    },
    //远程搜索方法,获取接口数据
    getOptionsData{
        //do something
    }
}