下拉框渲染大量数据时的解决方案
Posted 六月June June
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了下拉框渲染大量数据时的解决方案相关的知识,希望对你有一定的参考价值。
如果在下拉框中直接一次性渲染几百上千条数据可能导致页面卡死或报错,所以要分批次载入。使用频率较高,所以封装成一个组件,该组件效果类似于触底加载。支持搜索,且能够正常回显数据。该组件可拿来即用
组件代码
// 下拉框渲染多数据时的解决方案
<template>
<a-form-model-item :label="config.label" :prop="config.prop" :rules="rules">
<a-select
allowClear
show-search
style="width: 100%"
v-model="form[config.prop]"
option-filter-prop="children"
:placeholder="loading ? '正在加载...' : '请选择'"
:mode="mode"
:loading="loading"
:disabled="loading"
@popupScroll="handlePopupScroll"
@search="handleSearch"
@select="handleSelect"
>
<a-select-option v-for="(item, index) in options" :key="index" :value="item[config.code]">
item[config.name]
</a-select-option>
</a-select>
</a-form-model-item>
</template>
<script>
import debounce from 'lodash/debounce'
export default
props:
// 一个引用类型数据,达到双向绑定的作用
form: type: Object, default: () => ,
rules: type: Array, default: () => [] ,// 表单验证
originData: type: Array, default: () => [] ,// 原始数据
mode: type: String, default: 'default' ,// 多选还是单选 multiple为多选
// 配置项 label:'船舶名称',prop:'vesselName',code:'vesselId',name:'vesselName'
// code为下拉数据显示的值,name为下拉数据提交的值
config: type: Object, default: () => ,
,
data ()
// this.searchUser = debounce(this.searchUser, 800) // 防抖
return
searchName: null, // 下拉框搜索值
loading: false, // 下拉框数据加载
options: [], // 下拉框中载入数据
,
watch:
originData: function (newVal, oldVal)
if (newVal && newVal.length > 0)
this.getOptions(newVal)
,
,
methods:
// 得到下拉框中的载入数据
getOptions ()
if (this.searchName)
// 根据搜索值过滤数据
const data = this.originData.filter(
(x) => x[this.config.name] && x[this.config.name].indexOf(this.searchName) > -1
)
this.options = data
else
// 展示前20条数据
this.options = this.originData < 20 ? this.originData : this.originData.slice(0, 20)
// 用于回显 这样写就需要,先查询表单数据再查询下拉数据
if (this.form[this.config.prop])
// select的mode是否为多选
let data = []
if (this.mode === 'multiple')
data = this.originData.filter((x) => this.form[this.config.prop].includes(x[this.config.code]))
else
data = this.originData.filter((x) => this.form[this.config.prop] === x[this.config.code])
if (data && data.length > 0)
this.options = [...this.options, ...data]
,
// 下拉列表滚动事件
// 实现思路:当前下拉的展示列表+10小于全部数据的长度,newArr为新加载的10条数据,当前展示列表拼上新加载的10条;否则, newArr为全部列表中剩余的数据,当前展示列表拼上剩余的数据。
handlePopupScroll: debounce(function ()
if (this.loading === false)
const curLen = this.options.length
const allLen = this.originData.length
if (curLen + 10 < allLen)
const newArr = this.originData.slice(curLen, curLen + 10)
this.options = this.options.concat(newArr)
else
const newArr = this.originData.slice(curLen, allLen)
this.options = this.options.concat(newArr)
, 500),
// 搜索事件
handleSearch: debounce(function (val)
this.searchName = val
this.getOptions()
, 500),
// 选中事件
handleSelect ()
if (this.searchName)
this.searchName = null
this.getOptions()
,
,
</script>
使用组件
<template>
<a-form-model :model="form" :rules="rules">
<!-- 多选时需要添加mode="multiple",并且form里的member属性值要改为数组 -->
<SelectLimit
:form="form"
:rules="rules.member"
:originData="originData"
:config=" label: '船舶名称', prop: 'member', code: 'id', name: 'name' "
/>
</a-form-model>
</template>
<script>
import SelectLimit from '@/components/MyComponents/SelectLimit/index.vue' // 渲染多数据的下拉框
import query from '@/views/yangtze/express/vessel/service/vesselService' // 根据实际修改
export default
name: 'BaseForm',
components: SelectLimit ,
data ()
return
form:
// member: ['11240002','11240019'] ,// mode: 'multiple'
member: '11240002'
,
rules:
member: [ required: true, message: '必填' ],
,
originData: [], // 原始数据
,
mounted ()
this.queryOriginData() // 查询全部数据
,
methods:
// 查询全部数据
queryOriginData ()
const param = current: 1, pageSize: 100
query(param).then((res) =>
if (res.code === '0')
const data = res.data ||
const list = data.list || []
this.originData = list.map((x) => ( id: x.id, name: x.name )) // 得到全部数据
)
,
,
</script>
以上是关于下拉框渲染大量数据时的解决方案的主要内容,如果未能解决你的问题,请参考以下文章