100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > 【Antd+Vue】解决Antd select框渲染大量数据卡顿问题

【Antd+Vue】解决Antd select框渲染大量数据卡顿问题

时间:2019-10-19 15:24:27

相关推荐

【Antd+Vue】解决Antd select框渲染大量数据卡顿问题

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

一、模拟场景二、优化方案三、代码演示

一、模拟场景

在使用ant design vue开发时候,可能会遇到Select框需要加载几百条甚至上千条数据的场景。antd vue的select组件针对渲染大量数据的情况,暂时没做优化,因此每次点击select框都会感到卡顿。由于上次有小伙伴提出,想要纯前端实现的方法,因此我更新了这篇文章,下面是实现的效果预览:

二、优化方案

优化方案:初次加载30条左右(这个数量你可以自己决定,别太多就行)。当用户滚动下拉列表时,去加载更多数据。实现思路:主要是合理运用Select组件的popupScroll函数。为了节流控制,我们需要引入lodash库里面的debounce,达到防抖动的目的。

三、代码演示

下面是优化后的代码,有一些地方需要按实际修改,思路啥的都注释在代码里了

<template><a-form layout="inline"><a-form-item label="业务"><a-selectv-model="selectedVal":loading="dataLoading"placeholder="输入搜索内容"style="width: 240px;"show-searchoption-filter-prop="children"@search="handleSearch"@popupScroll="handlePopupScroll"@select="handleSelect"><a-select-option v-for="item in renderedOptions" :value="item" :key="item">{{ item }}</a-select-option></a-select></a-form-item></a-form></template>

<script>import debounce from 'lodash/debounce'import {fetchBusinessList } from '@/api/public' // 根据实际修改const LOAD_NUM = 30 // 加载条数--可自定义export default {name: 'BaseForm',data () {return {selectedVal: '', // Select框选中的值oriDataList: [], // 原数据列表 -- 从接口获取dataLoading: false, // 原数据列表的加载状态 -- 接口的响应状态searchVal: '', // 搜索的内容filterDataList: [], // 过滤的数据列表 -- 从dataList中过滤出含搜索内容的数据renderedOptions: [] // 已渲染的下拉列表}},mounted () {this.getDataList()},methods: {// 获取数据源,并取数据源的前n条作为下拉列表的可选项getDataList () {this.dataLoading = truefetchBusinessList().then(res => {this.dataLoading = falsethis.oriDataList = res.result // 该接口返回的数据存放在res.result(根据实际自行修改)this.renderedOptions = this.oriDataList.slice(0, LOAD_NUM)})},// 文本框值变化时触发 -- 从数据源中过滤出含搜索内容的数据,并取过滤结果的前n条作为下拉列表的可选项handleSearch (val) {this.searchVal = vallet filterList = []if (val) {filterList = (this.oriDataList).filter(item => item.indexOf(val) > -1)} else {filterList = this.oriDataList}this.filterDataList = filterListthis.renderedOptions = 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.renderedOptions.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.renderedOptions = (this.renderedOptions).concat(addList)}},// 被选中时调用,参数为选中项的 value (或 key) 值handleSelect (val) {if (this.searchVal) {const selectedArr = (this.oriDataList).filter(item => item === val) // 从数据源中过滤出下拉框选中的值,并返回一个数组const restList = (this.oriDataList).filter(item => item !== val) // 从数据源中过滤出其他的值,返回一个数组const newList = selectedArr.concat(restList).slice(0, LOAD_NUM) // 将选中的元素放到下拉列表的第一位this.renderedOptions = newList // 更新已渲染的下拉列表this.oriDataList = selectedArr.concat(restList) // 更新数据源this.searchVal = '' // 因为触发handleSelect函数时,会自动清空用户输入的内容。因此,searchVal需要重置。}}}}</script>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。