目录

一、概述

二、详解


一、概述

select组件一般加载几百条数据就会出现卡顿现象,原因是antd vue的select组件针对加载大量数据的情况,暂时没做优化,因此每次点击select组件都会出现卡顿。本文将已纯前端的方式解决该问题。

二、详解

方案:初始加载一部分数据,后续随滚动条滚动陆续加载。

步骤一:模板代码

<a-select
  v-model="demoValue"
  show-search
  option-filter-prop="children"
  @popupScroll="handlePopupScroll"
  @search="handleSearch"
  @select="handleSelect"
  @dropdownVisibleChange="handleDropdownVisibleChange"
>
  <a-select-option
    v-for="data in arrs"
    :key="data.id"
  >
    {{ data.name }}
  </a-select-option>
</a-select>

步骤二:基本参数

<script>
// debounce可用来创建一个防抖函数
import debounce from 'lodash/debounce';

export default {
    data() {
        return {
            arrs: [], // 数据源, 页面初始加载时直接访问接口获得
            showList: [], // 下拉框实时展示的数据
            filterDataList: [], // 使用过滤条件后,下拉框展示的数据源
            searchText: '' // 下拉框的筛选条件 
        }
    }
};    
</script>

步骤三:创建原始数据监听器

<script>
export default {
    watch: {
        // 监听原始数据的变动,及时更新下拉框展示数据
        arrs: {
            handler(newValue) {
                this.showList = newValue.slice(0, 10);
            },
            immediate: true
        }
    }
};    
</script>

步骤四:滚动条的回调函数

<script>
export default {
    methods: {
        handlePopupScroll: debounce(function () {
            if (this.searchText === '') {
                this.loadMoreData(this.arrs);
            } else {
                // 存在过滤条件时,从filters数据源中加载数据
                this.loadMoreData(this.filterDataList);
            }
        }, 400)
    }
};    
</script>

步骤五:文本框值变化时的回调函数

<script>
export default {
    methods: {
        handleSearch(val) {
            this.searchVText = val;
            let temp = [];
            if (val) {
                temp = this.arrs.filter(p => p.name.indexOf(val) > -1);
            } else {
                temp = this.arrs;
            }
            this.filterDataList = temp ;
            this.showList= temp .length < 10 ? temp : temp .slice(0, 10);
        }
    }
};    
</script>

步骤六:被选中时的回调函数

<script>
export default {
    methods: {
        handleSelect(val) {
            // 选中的数据
            const selected = (this.arrs).filter(item => item.code === val);
            // 没有选中的数据
            const noSelected = (this.arrs).filter(item => item.code !== val);
            // 重新调整原始数据,选中的排在第一位
            this.arrs = selected.concat(noSelected);
            // 清空查询条件
            if (this.searchText) {
                this.searchText = '';
            }
        }
    }
};    
</script>

步骤七:下拉框打开时的回调函数

<script>
export default {
    methods: {
        handleDropdownVisibleChange(open) {
            if (open) {
                // 下拉框打开时重置展示的数据
                this.showList= this.arrs.slice(0, 10);
            }
        }
    }
};    
</script>

步骤八:更新下拉框展示的数据

<script>
export default {
    methods: {
        loadMoreData(dataList) {
            // 已渲染的下拉列表长度
            const length = this.showList.length; 
            // 当前数据源的长度
            const total = dataList.length; 
            // 新加载的数据
            let addList = [];
            if (length < total) {
                if (length + 10 <= total) {
                    addList = dataList.slice(length, length + 10);
                } else {
                    addList = dataList.slice(length, length + (total % 10));
                }
                // 更新下拉框展示的数据
                this.showList= (this.showList).concat(addList);
            }
        }
    }
};    
</script>

 

Logo

前往低代码交流专区

更多推荐