美文网首页
解决Antd select框渲染大量数据卡顿问题

解决Antd select框渲染大量数据卡顿问题

作者: 喜欢走弯路的人 | 来源:发表于2022-11-10 11:35 被阅读0次

    一、场景:一个下拉框中加载上百条、上千条数据,导致下拉框数据卡顿

    二、解决方案:

    1、初次加载30条左右(这个数量自己决定),当用户滚动下拉列表时,去加载更多数据。

    2、合理运用Select组件的popupScroll函数。为了节流控制,我们需要引入lodash库里面的debounce,达到防抖动的目的。

    3、使用局部混入,在需要的地方引入即可

    4、关键点:任意一个下拉框,主要要使用search、popupScroll、select三个操作事件,同时添加下拉框可搜索filterOption方法

            filterOption(input, option) {// 下拉框可搜索

                return (

                    option.componentOptions.children[0].text

                    .toLowerCase()

                    .indexOf(input.toLowerCase()) >= 0

                );

            },

    三、代码示例:

    vue:

    vue

    js:

    1、把js代码写在了局部混入selectOptions.js文件中,在需要的vue页面引入局部混入,如下图所示

    selectOptions.js局部混入引入方法

    2、使用:

    调用接口后的使用方法

    3、selectOptions.js文件代码如下:

    selectOption.js

    为方便大家复制,这里将selectOption.js粘贴如下

    import debounce from 'lodash/debounce'

    const LOAD_NUM = 30 // 加载条数--可自定义

    export const selectOptions = {

        data(){

            return{

                selectedVal: '', // Select框选中的值

                oriDataList: [], // 原数据列表 -- 从接口获取

                dataLoading: false, // 原数据列表的加载状态 -- 接口的响应状态

                searchVal: '', // 搜索的内容

                filterDataList: [], // 过滤的数据列表 -- 从dataList中过滤出含搜索内容的数据

            }

        },

        methods: {

            // 获取数据源,并取数据源的前n条作为下拉列表的可选项

            getSelectList (resData) {

                this.oriDataList = resData // 该接口返回的数据存放在res.result(根据实际自行修改)

                return this.oriDataList.slice(0, LOAD_NUM)

            },

            // 文本框值变化时触发 -- 从数据源中过滤出含搜索内容的数据,并取过滤结果的前n条作为下拉列表的可选项

            handleSearch (val) {

                this.searchVal = val

                let filterList = []

                if (val) {

                    filterList = (this.oriDataList).filter(item => item.name.indexOf(val) > -1)

                } else {

                    filterList = this.oriDataList

                }

                this.filterDataList = filterList

                this.tagList = filterList.length < LOAD_NUM ? filterList : filterList.slice(0, LOAD_NUM)

            },

            // 滚动时触发(防止抖动)

            handlePopupScroll: debounce(function () {

                if (this.searchVal === '') {

                    this.loadMoreData(this.oriDataList)

                } else {

                    this.loadMoreData(this.filterDataList)

                }

            }, 400),

            // 加载更多数据到select框

            loadMoreData (dataList) {

                const renderedLen = this.tagList.length // 已渲染的下拉列表长度

                const totalLen = dataList.length // 当前数据源的长度

                let addList = []

                if (renderedLen < totalLen) {

                    if (renderedLen + LOAD_NUM <= totalLen) {

                    addList = dataList.slice(renderedLen, renderedLen + LOAD_NUM)

                    } else {

                    addList = dataList.slice(renderedLen, renderedLen + (totalLen % LOAD_NUM))

                    }

                    this.tagList = (this.tagList).concat(addList)

                }

            },

            // 被选中时调用,参数为选中项的 value (或 key) 值

            handleSelect (val) {

                if (this.searchVal) {

                    const selectedArr = (this.oriDataList).filter(item => item.name === this.searchVal) // 从数据源中过滤出下拉框选中的值,并返回一个数组

                    const restList = (this.oriDataList).filter(item => item.name !== this.searchVal) // 从数据源中过滤出其他的值,返回一个数组

                    const newList = selectedArr.concat(restList).slice(0, LOAD_NUM) // 将选中的元素放到下拉列表的第一位

                    this.tagList = newList // 更新已渲染的下拉列表

                    this.oriDataList = selectedArr.concat(restList) // 更新数据源

                    this.searchVal = '' // 因为触发handleSelect函数时,会自动清空用户输入的内容。因此,searchVal需要重置。

                }

            }

      }

    }

    相关文章

      网友评论

          本文标题:解决Antd select框渲染大量数据卡顿问题

          本文链接:https://www.haomeiwen.com/subject/otpztdtx.html