浅谈ElementUI el-select 数据过多解决办法

目录
  • 1. 场景描述
  • 2.解决办法
  • el-select组件的options条数过多时的解决方案
    • 业务场景
    • 解决思路
    • 注意事项

1. 场景描述

不知道你有没有这样的经历,下拉框的选项很多,上万个选项甚至更多,这个时候如果全部把数据放到下拉框中渲染出来,浏览器会卡死,体验会特别不好

用人会说element-ui的select有一个remote-method,支持远程搜索,我们让服务端支持一下不就可以了,当然这是一种解决的方案。但是有时候这种方法有时候不一定适用

(1)有时候服务端数据是经过计算返回给我们的,可能返回不是特别快,体验不是很好
(2)有时候数据可能只有几千条,全部渲染又不太合适,一直掉接口不是特别好
(3)仅仅通过前端能不能解决,如果能解决,岂不是减轻了服务端的工作和压力

2.解决办法

1 ) 分段加载:也不加载下拉项,通过点击下拉框的时候,再去加载,此时的选项全部加载进来,该种情况只适用于缓加载情况,需要点击加载完后才能下拉选项,体验一般。
2 )提示:element-ui的select有一个filter-method方法,我们可以通过这个方法来进行过滤下拉项
假设我们有个下拉框是用来选择用户的

<el-select
  v-model="userId"
  filterable
  :filter-method="userFilter"
  clearable>
  <el-option
    v-for="item in userList"
    :key="item.userId"
    :label="item.username"
    :value="item.userId"
  ></el-option>
</el-select>
userFilter(query = '') {
  let arr = this.allUserList.filter((item) => {
    return item.username.includes(query) || item.userId.includes(query)
  })
  if (arr.length > 50) {
    this.userList = arr.slice(0, 50)
  } else {
    this.userList = arr
  }
},
getUserWhiteList() {
  HttpRequest.post("/api/admin/community/getUserWhiteList").then(
    response => {
      this.allUserList = response.data.list;
      this.userFilter()
    }
  );
},

如上所示,我们从后台获取用户列表,经过我们自己的过滤,我们每次只渲染50条数据,无论有多少数据,对我们来说也支持一个变量,占个内存。当然数据越多,数组的遍历也会相应的慢,但是这个影响不大。
我们不仅能过滤名字,还可以对我们制定的任一项进行过滤
优化:上面的代码我们还可以适当优化下,只有发现了数组长度超过了50项,我们就停止遍历

el-select组件的options条数过多时的解决方案

业务场景

当使用el-select组件时,如果options数量过多,会存在的弊端:

页面渲染出大量el-option节点,会导致页面卡顿甚至卡死,用户体验极差。
选择时条目众多,查找困难。

本次我遇到的场景是options数量为6-9千的情况。

解决思路

从总options中取出固定条目的小option(renderOption)用于页面渲染,利用el-select提供的
filter-method方法进行搜索过滤,在搜索时用过滤结果更新renderOption。

代码实现
下面是vue的组件封装

<template>
    <el-select
        class="yt-select"
        v-model="currValue"
        filterable
        v-bind="$attrs"
        :filter-method="userFilter"
        :disabled="disabled"
        :clearable="clearable"
        @change="change"
    >
        <el-option
            v-for="option in renderOption"
            :key="option.value"
            :value="option.value"
            :label="option.label"
        >{{ option.label }}</el-option>
    </el-select>
</template>

<script>

export default {
    name: 'easy-select',
    props: {
        value: {
            type: [String, Number],
            default: ''
        },
        max: {
            type: Number,
            default: 30
        },
        disabled: {
            type: Boolean,
            default: false
        },
        clearable: {
            type: Boolean,
            default: true
        },
        options: {
            type: Array,
            default: () => []
        }
    },
    data () {
        return {
            renderOption: []
        }
    },
    computed: {
        currValue: {
            get () {
                return this.value || ''
            },
            set (value) {
                this.$emit('input', value)
            }
        }
    },
    watch: {
        value () {
            this.addValueOptions()
        },
        options: {
            handler (V) {
                this.init()
            },
            deep: true
        }
    },
    created () {
        this.init()
    },
    methods: {
        async init () {
            this.userFilter()
            this.addValueOptions()
        },
        addValueOptions () {
            if (this.currValue) {
                let target = this.options.find((item) => { // 从大option中找到当前条
                    return item.value === this.currValue
                })
                if (target) { // 将当前条与小option比对,没有则加入
                    if (this.renderOption.every(item => item.value !== target.value)) {
                        this.renderOption.unshift(target)
                    }
                }
            }
        },
        addFilterOptions (label) {
         // 每次查找输入时,若有精确匹配的条目,保证该条目一定在renderOption内
            let target = this.options.find((item) => { // 从大option中找到当前条
                return item.label === label
            })
            if (target) { // 将当前条与小option比对,没有则加入
                if (this.renderOption.every(item => item.label !== target.label)) {
                    this.renderOption.unshift(target)
                }
            }
        },
        userFilter (query = '') {
            let arr = this.options.filter((item) => {
                return item.label.includes(query) || item.value.includes(query)
            })
            if (arr.length > this.max) {
                this.renderOption = arr.slice(0, this.max)
                this.addFilterOptions(query)
            } else {
                this.renderOption = arr
            }
        },
        change (value) {
            this.$emit('change', value)
            if (!value) { // 单选清空-optons初始化下
                this.userFilter()
            }
        }
    }
}
</script>

注意事项

  • 初始化和value值变化时,需要找到value对应具体项,并加入renderOptions
  • 搜索时,可能过滤到的n条数据都没有包含用户想找的具体项,因此,过滤时需要进行一下精确查找,将匹配项放入renderOptions头部

到此这篇关于ElementUI el-select 数据过多解决办法的文章就介绍到这了,更多相关ElementUI el-select 数据过多内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue2.0 element-ui中el-select选择器无法显示选中的内容(解决方法)

    我使用的是element-ui V2.2.3.代码如下,当我选择值得时候,el-select选择器无法显示选中的内容,但是能触发change方法,并且能输出选择的值. select.vue文件 <template> <div> <div class="row" v-for="RowItem in rows"> <div class="col" v-for="colItem in RowItem.

  • Vue + Element-ui的下拉框el-select获取额外参数详解

    直接上代码吧~ <el-table-column label="用户类型" width="180"> <template slot-scope="scope"> <el-select v-model="scope.row.roleID" placeholder="请选择" @change="changeRole($event,scope)"> <

  • 解决vue elementUI 使用el-select 时 change事件的触发问题

    如下所示: <el-select v-model="level" size="mini" placeholder="请选择" :change="selectChange()"> <el-option v-for="item in select" :key="item.value" :label="item.label" :value="it

  • 详解element-ui中el-select的默认选择项问题

    直接绑定将option中的value值绑定给v-model <template> <div> <el-select v-model="query"> <el-option v-for="item in options" :key="item.value" :value="item.value" :label="item.label"></el-optio

  • element-ui 远程搜索组件el-select在项目中组件化的实现代码

    在项目中发现使用el-select时写的比较多重复代码,还有就是同一个页面使用el-select会出现label值会显示value值, el-select组件化: <template> <el-select :class="obj&&keyword[keywordAttr.label]? 'selected': ''" :value="keyword" :placeholder="obj && keywor

  • 解决element-ui里的下拉多选框 el-select 时,默认值不可删除问题

    这是一个项目中常见的需求,el-select 为下拉多选,默认值不可删除,或者指定值不可删除. 实现效果: el-select 如下源码中 tag closable 属性为 el-select 的 disabled 属性,所有明显不支持. 解决思路(从el-select 的角度来考虑,其他组件组合的情况暂不考虑) 想要实现某些选项是不删除,1.需要tag 不可删除,2.options 不可选择 options 不可选择很好实现,只需要给一个disabled属性.tag 不可删除才是关键.下面是我

  • 浅谈ElementUI el-select 数据过多解决办法

    目录 1. 场景描述 2.解决办法 el-select组件的options条数过多时的解决方案 业务场景 解决思路 注意事项 1. 场景描述 不知道你有没有这样的经历,下拉框的选项很多,上万个选项甚至更多,这个时候如果全部把数据放到下拉框中渲染出来,浏览器会卡死,体验会特别不好 用人会说element-ui的select有一个remote-method,支持远程搜索,我们让服务端支持一下不就可以了,当然这是一种解决的方案.但是有时候这种方法有时候不一定适用 (1)有时候服务端数据是经过计算返回给

  • 浅谈ElementUI中switch回调函数change的参数问题

    需求说明 八个switch组件,用同一个回调函数 switch组件状态发生变化时需要知道它目前开关状态 需要知道当前是哪个switch 问题描述 按照官方文档对switch事件的描述 事件名称 说明 回调参数 change switch 状态发生变化时的回调函数 新状态的值 下面这样写可以满足第二个需求,change回调函数中的参数callback就是开关当前的状态值,默认是boolean类型,但是第三个需求还不能解决. <el-switch v-model="value1" @

  • 浅谈入门级oracle数据库数据导入导出步骤

    oracle数据库数据导入导出步骤(入门) 说明: 1.数据库数据导入导出方法有多种,可以通过exp/imp命令导入导出,也可以用第三方工具导出,如:PLSQL 2.如果熟悉命令,建议用exp/imp命令导入导出,避免第三方工具版本差异引起的问题,同时效率更高,但特别注意:采用命令时要注意所使用的用户及其权限等细节. 3.在目标数据库导入时需要创建与导出时相同的用户名(尽量一致),并赋予不低于导出时用户的权限:同时还需创建与原数据库相同的表空间名,若本地数据库已存在相同的表空间,则只能进行表空间

  • 浅谈vue获得后台数据无法显示到table上面的坑

    因为刚学vue然后自己自习了一下axios,然后想写一个简单的查询后台数据 <tr v-for=" user in uList"> <td>{{user.id}}</td> <td>{{user.name}}</td> <td>{{user.gender}}</td> </td> </tr> 然后先是写了这样一个代码 created: function () { axios.ge

  • 浅谈MySQL之select优化方案

    目录 生活中的例子 慢查询 如何去优化 count limit 最大值最小值min&max 生活中的例子 我们是否看到过在公司中许多查询语句都是select * xxxx 心中的想法肯定是,别人写了select *,那我写吧,省去了不少麻烦事儿 慢查询 首先去思考,最基本的,是否我们使用的数据库插查询语句存在了访问的数据太多 其实大部分性能低的查询往往都可以通过减少访问的数据量来优化的 因为select * 会给服务器带来额外的I/O.内存和cpu的消耗 数据库中慢查询开销的三个指标 相应时间

  • 浅谈JVM内存溢出原因和解决思路

    目录 栈溢出(虚拟机栈和本地方法栈) 产生原因 解决思路 堆溢出 产生原因 解决思路 方法区和运行时常量池溢出 产生原因 解决思路 本机直接内存溢出 产生原因 解决思路 栈溢出(虚拟机栈和本地方法栈) 产生原因 在HotSpot中,只能由-Xss参数来设定.因为在HotSpot中不区分虚拟机栈和本地方法栈的. 栈溢出时会出现两种异常:StackOverflowError异常和OutOfMemoryError异常. StackOverflowError异常因为线程请求的栈深度大于虚拟机允许的最大深

  • 浅谈JS中json数据的处理

    1. json数据结构(对象和数组) json对象:var obj = {"name":"xiao","age":12}; json数组:var objArray = [{"name":"xiao","age":12},{"name":"xiao","age":12}]; 2. 处理json数据,依赖文件有:jQuery.js

  • 浅谈python实现Google翻译PDF,解决换行的问题

    我们复制PDF到Google翻译时,总是会出现换行的情况,如果自己手动去除,那就太麻烦了. 那么用Python就可以解决,复制到粘贴板以后,Python程序自动可以把\n换成空格,然后我们就可以复制到Google翻译中去 代码: import pyperclip import time import webbrowser copyBuff=' ' while True: time.sleep(10) copyedText=pyperclip.paste() if copyBuff!=copyed

  • 浅谈pycharm出现卡顿的解决方法

    使用pycharm时常出现   the IDE is running low on memory 的问题,表示pycharm这款IDE使用内存不足,需要在系统内存充足的情况下扩充IDE memory. 首先,打开File -> Appearance ->Windows Options -> 选中show memmory indicator -> OK 右下角会出现  左边数字为已使用IDE memory,右边数字为总共的IDE memory,初始为750M,如果pycharm出现卡

  • 浅谈IDEA中Maven配置问题全解决

    最近换了工作环境,以前的IDEA配置都没了,记得上次配置自己的IDEA还是在两年前?然后构建Maven项目时遇到了一些小插曲,记录下解决方案(PS:新手教程向) 1. idea中maven默认配置的坑 首先打开File->Settings 这里可以直接搜索maven,就可以进入idea的Maven配置选项. 我这里是idea默认的maven配置,可以看到默认的Maven目录是idea内置的maven插件目录,同时Maven的配置文件在操作系统的User目录下. 理论上来讲idea的默认配置这样是

随机推荐