iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >浅谈ElementUI el-select 数据过多解决办法
  • 586
分享到

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

2024-04-02 19:04:59 586人浏览 八月长安
摘要

目录1. 场景描述2.解决办法 el-select组件的options条数过多时的解决方案 业务场景解决思路注意事项1. 场景描述 不知道你有没有这样的经历,下

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 数据过多内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 浅谈ElementUI el-select 数据过多解决办法

本文链接: https://www.lsjlt.com/news/135483.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 浅谈ElementUI el-select 数据过多解决办法
    目录1. 场景描述2.解决办法 el-select组件的options条数过多时的解决方案 业务场景解决思路注意事项1. 场景描述 不知道你有没有这样的经历,下...
    99+
    2022-11-12
  • 如何解决el-select数据过多懒加载问题
    这篇文章主要介绍如何解决el-select数据过多懒加载问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!el-select数据过多处理方式在日常项目中el-select组件的使用频...
    99+
    2022-10-19
  • 浅谈利用Spring的AbstractRoutingDataSource解决多数据源的问题
    在互联网的服务端开发的时候,我们很经常要在一个项目中去调用不同的数据库。在这种情况下,必然要涉及到多数据源问题。那么,我们该如何解决多数据源问题呢?有没有一种方法来动态切换数据源呢?答案是有的。万能的Spring已经给了我们解决方案——利用...
    99+
    2023-05-31
    spring abstractroutingdatasource dat
  • sql查询数据过多内存溢出的解决方法
    这篇文章主要介绍sql查询数据过多内存溢出的解决方法,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!正常来说,一般是不会出现这种情况的,但也不能保证,偶尔有这种情况发生,解决方案如下:...
    99+
    2022-10-18
  • Discuz 密码错误次数过多导致等待15分钟的解决办法
    Discuz 密码错误次数过多导致等待15分钟的解决办法 修改文件:在function/function_member.php找 $return = (!$login || (TIMESTAMP - $login['la...
    99+
    2022-06-12
    Discuz 密码错误
  • 公司仓库数据库服务器死锁过程及解决办法是什么
    这篇文章将为大家详细讲解有关公司仓库数据库服务器死锁过程及解决办法是什么,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。死锁的四个必要条件:互斥条件(Mutu...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作