实现效果
实现思路
- 初始化加载第一页;
- 监听下拉框的滚动事件,当滚动到底部的时候加载下一页;
- 输入搜索时,重置为第一页加载;
- 关闭下拉选择框时,判断如果存在搜索值,要清空搜索值、并加载第一页。
实现代码
html
html
<a-select
v-model:value="values"
:mode="multiple"
:show-search="true"
:filter-option="false"
:default-active-first-option="false"
@popupScroll="onPopupScroll"
@search="onSearch"
@dropdownVisibleChange="onDropdownVisibleChange"
>
<a-select-option v-for="item in optionList" :key="`${item.value}-${refreshFlag}`" :value="item.value">
<div :title="item.label">{{ item.label }}</div>
</a-select-option>
<a-select-option v-if="loading" disabled value="loading">
<a-spin :spinning="true"></a-spin>
</a-select-option>
</a-select>
ts
typescript
const optionList = ref<{ label: string; value: string }[]>([]);
const loading = ref<boolean>(false);
const keyWord = ref<string>('');
const curPage = ref<number>(0);
const total = ref<number>(0);
const refreshFlag = ref<number>(1);
// 最终搜索接口
const onRelationSearch = debounce(async (page = 1, curlist = []) => {
try {
const params: any = {
condition: {
keyWord: keyWord.value,
},
paging: {
pageIndex: page,
pageSize: 20,
},
};
const res = await oneFunction(params);
const dataList = res?.result || [];
optionList.value = [
...curlist,
...dataList
.map((item: any) => {
return {
label: item.name,
value: item.id,
};
});
];
refreshFlag.value++;
curPage.value = page;
total.value = res?.result?.pageResult?.totalCount || 0;
} finally {
loading.value = false;
}
}, 300);
// 搜索前置判断
const getListBefore = (page: number, list: { label: string; value: string }[]) => {
// _props传入 分页, 现有列表,输入框内容
// 当不是第一页切 列表数量大于等于总数时终止掉
if (page !== 1 && list.length >= total.value) {
message.warning('没有更多数据了');
} else if (loading.value) {
// 如果处于加载中也终止掉
return;
}
// 请求,加载中
loading.value = true;
// 请求接口
onRelationSearch(page, list);
};
// 滚动事件
const onPopupScroll = (event: any) => {
const { target } = event;
if (target.scrollTop + target.offsetHeight === target.scrollHeight) {
// 调用加载数据,传入需求请求的分页
getListBefore(curPage.value + 1, optionList.value);
}
};
// 搜索事件
const onSearch = (value: any) => {
loading.value = false;
optionList.value = [];
keyWord.value = value;
getListBefore(1, []);
};
const onDropdownVisibleChange = debounce((open: boolean) => {
if (!open && keyWord.value) {
loading.value = false;
keyWord.value = '';
optionList.value = [];
getListBefore(1, []);
}
}, 300);