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

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

二、解决方案:

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框渲染大量数据卡顿问题)