代码编织梦想

「🚀」场景

近期着手开发基于ElementUI的后台管理系统,偶然间发现「el-select」下拉选择时候遇到一个问题,当渲染下拉选项的「options」的数据量过多时「本项目中的数据条目已过万」,就会出现下拉选择器卡顿的情况,尤其是在模糊匹配过滤的情况下,显得十分的卡顿。初始化选择器的时候,也会点击无反应,有时候需要点击多次才可出现「dialog」弹窗(本次下拉筛选在弹窗中实现)。 翻阅多篇博客笔记之后,最终找到一个可以解决问题的方案,现将此次优化方案记录成为笔记,以便于日后遇到类似问题的时候便于查阅。

「📷」图示

image.png

⚠️注:基于select的下拉筛选,通过自定义事件来实现模糊搜索匹配。

  • 一共两种方案:

    • 一是获取所有数据,通过输入的关键字自己对获取的数据进行过滤处理;
    • 二是通过输入的关键字来动态请求后台接口,通过接口返回的数据来动态渲染下拉选项;

「🍵」代码实现

  • 🌰Vue组件实例
<template>
  <div class="app">
    <el-dialog title="标题" :visible.sync="relatedOpen" :append-to-body="true" width="500px">
      <el-row :gutter="16">
        <el-col :span="20">
          <el-select
            v-model="value"
            filterable
            clearable
            style="width:100%"
            placeholder="请选择"
            :loading="searchLoad"
            :filter-method="filterMethod"
            v-el-select-loadmore="loadMore(rangeNumber)"
            @visible-change="visibleChange"
          >
            <el-option v-for="item in options.slice(0, rangeNumber)" :key="item.key" :label="item.value" :value="item.key"></el-option>
          </el-select>
        </el-col>
        <el-col :span="4">
          <el-button type="primary" @click="submit">确定</el-button>
        </el-col>
      </el-row>
    </el-dialog>
  </div>
</template>
  • 🚗「v-el-select-loadmore」为自定义指令封装的数据加载指令,是为了解决和优化elementUI下拉选择器加载数据过多出现卡顿问题的。
  • 🚴「filter-method」是下拉选择器的一个自定义属性,可以监听输入的变量,从而依据变量来实现数据的动态获取;
  // 自定义指令
  directives: {
    "el-select-loadmore": (el, binding) => {
      // 获取element UI定义好的scroll元素
      const SELECTWRAP_ROM = el.querySelector(".el-select-dropdown .el-select-dropdown__wrap");
      if (SELECTWRAP_ROM) {
    // 添加scroll事件
        SELECTWRAP_ROM.addEventListener("scroll", function() {
      // 判断滚动
          const condition = this.scrollHeight - this.scrollTop <= this.clientHeight;
          condition && binding.value();
        });
      }
    }
  }
  • 相应的数据函数
export default {
  data() {
    return {
      relatedOpen: false,
      options: [] /* 选择下拉框的值 */,
      courseList: [],
      rangeNumber: 10,
      searchLoad: false /* 下拉框的loading状态 */,
      value: "",
      timer: null
    };
  },
  created() {
    this.getOptions();
  },
  methods: {
    // 按需加载
    loadMore(n) {
      return () => (this.rangeNumber += 5);
    },
    // 过滤课件
    filterMethod(query) {
      if (this.timer != null) clearTimeout(this.timer);
      !this.searchLoad && (this.searchLoad = true);
      this.timer = setTimeout(() => {
        this.options = !!query ? this.courseList.filter(el => el.value.toLowerCase().includes(query.toLowerCase())) : this.courseList;
        clearTimeout(this.timer);
        this.searchLoad = false;
        this.rangeNumber = 10;
        this.timer = null;
      }, 500);
    },
    // 监听select下拉框的显示和隐藏
    visibleChange(flag) {
      // 显示时初始化列表
      flag && this.filterMethod("");
      // 初始化默认值
      this.rangeNumber = 10;
    },
    // 获取选项
    async getOptions() {
      await searchCourseware().then(res => {
        let list = res.data || [];
        // 默认展示的数据
        this.options = list;
        // 原始数据
        this.courseList = list;
      });
    }
  }
}

注:

  • 定时器作用是防止输入筛选的关键字太过频繁,从而造成数据响应不及时;因为本次是一次性获取了全部的数据,所以这里只是用做渲染加载数据;
  • 选择器的事件函数主要是用来初始化“获取焦点”和“失去焦点”时处理默认展示数据用的,若是获取的网络请求,此处需要做“函数截流”处理;目的是减少接口请求次数。

「🍎」总结:

换了新的工作环境,现开始着手做后台管理系统,或多或少会遇到各种各样的问题。一如即往,会在笔记中记录开发中遇到的问题。好记性不如烂笔头,希望现在埋下种子,等到来年秋天的时候会收获🍒果实。JY

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/SK_21/article/details/120472431

el-select数据过多懒加载(loadmore)-爱代码爱编程

el-select数据过多处理方式 在日常项目中el-select组件的使用频率是非常之高的. 当数据过多时渲染时间非常长, 这里提供几个处理方式. 远程搜索 组件提供了远程搜索方式, 也就是按照你输入的结果匹配选项. 官网提供了参考示例; 这里不加赘述. 下拉懒加载loadMore 下拉懒加载, 当select滚动到底部时,

element-select当下拉框数据过多使用懒加载_otwayalways的博客-爱代码爱编程

分页原理,设置高度,当超过一个高度再加载一页数据,以此类推。 <template> <el-select v-model="value" placeholder="请选择" filterable multiple v-el-select-loadmo

[ element-ui ] select 开启远程搜索后, 数据量过多的交互优化_付出总会有收获的博客-爱代码爱编程

下拉列表的数据如果过多的话, 用户用起来会十分麻烦, 100多条的数据, 总不能让用户一直往下拉去找她要的那条, 所以远程搜索就用上了, 用户一直输入关键字, 一直匹配. 但是如果是第一次点开下拉列表, 数据过多会导致

vue+elementui1.x tree组件数据太多时加载过慢的解决方案_weixin_34258838的博客-爱代码爱编程

2019独角兽企业重金招聘Python工程师标准>>> 在使用elementui1.x的tree组件时,如果数据量多大,那么在加载dom树,尤其是搜索的时候,数据非常缓慢 解决 添加是否查询的变量开关:ifquery +默认 ifquery设置为false在加载的时候,先加载数据的一层和二层,将二层以下

element-ui中el-select下拉框选项过多的优化方案-爱代码爱编程

el-select中options数据超过3000条就会造成前端页面明显卡顿,本次我的遇到的业务场景数据是近2w条,因此在不优化的情况下页面压根无法使用,下面给出我的优化过程。 一种优化思路:  element-ui的select有一个remote-method,支持远程搜索,我们让服务端支持一下不就可以了,当然这是一种解决的方案。但是有时候这种方法对

element-ui中select下拉框加载大数据渲染优化-爱代码爱编程

现在的前端项目中对于element-ui的使用几乎已经是一个常规动作了,但是组件库中的ui组件不一定都能满足实际场景的需求,比如今天要讲的select下拉框选择组件。 我们公司是做证券行业基础设施的,股票和证券的数量动不动就是上千,当使用select渲染的时候就会很有压力,我司大致3000条数据,全部渲染出来大致需要4s左右,并且多选模式时,选中和反选时

实现Element UI中下拉框滚动加载-爱代码爱编程

实现Element UI中下拉框滚动加载 Vue.directive('loadmore', { bind (el, binding) { // 获取element-ui定义好的scroll盒子 const SELECTWRAP_DOM = el.querySelector('.el-sel

解决 Element-ui中 选择器(Select)因options 数据量大导致渲染慢、页面卡顿的问题-爱代码爱编程

业务场景:服务端返回两万多条数据需要在下拉框中展示,直接渲染会导致页面卡顿且需要很长时间等待,用户体验极差,所以我们把这个el-select优化一下,直接上代码。 相关知识传送门:Vue实现自定义指令(directive)及应用场景Vue中 实现函数的防抖、节流及应用场景 <template> <div class="conten

element 动态加载下拉框_在element-ui的select下拉框加上滚动加载-爱代码爱编程

在项目中,我们需要运用到很多来自后端返回的数据。有时是上百条,有时甚至上千条。如果加上后端的多表查询或者数据量过大,这就导致在前端的显示就会及其慢,特别是在网络不好的时候更是如此。 自然,后端就做了一项非常“漂亮”的交互体验数据——分页 这不分页还好,一分页对超过10条数据之后的本来也不多,就20条,偏偏还得做个分页器。(假设为10条) 此时,如

element 动态加载下拉框_动态增加select框(elementUI 框架)-爱代码爱编程

演示动态增加select框(elementUI 框架) @import url("https://unpkg.com/element-ui/lib/theme-chalk/index.css"); 增加 删除 提交 var vue = new Vue({ el: '#app', data() {

vue 下拉框大数据慢_Vue:解决 element-ui 下拉框过多导致卡顿问题-爱代码爱编程

标签: Vue element-ui 原因:下拉框数据过多,若渲染全部数据,会导致 DOM 数量太多,操作卡顿。 解决办法:将获取的数据(allList)和渲染数据(list)分离开,限制渲染数组的长度。 v-for="item in allList" :key="item.value" :label="item.label

vue+elementui el-select选择框异步请求选项列表,$set之后显示的value值-爱代码爱编程

场景 两个el-select 联动的选择框,选完第一个框异步加载第二个框的选项列表并给第二个选项赋值为选项的第一个值 <template> <el-select v-model="formData.data1" @change="onChange" > <el

【性能优化】vue+element-ui中el-select大数据优化-爱代码爱编程

当el-select数据超过1000条,页面就会出现明显卡顿。此时的优化方案除了后台接口分页,前台也可以自行数据分页: <el-select filterable v-model.trim="formInline.storeId" :placeholder="$t('SearchNameAll.PleaseChoose')" @change="g