日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Vue3+Ts笔记:基于element-UI 实现下拉框滚动翻页查询通用组件

發布時間:2025/6/17 编程问答 27 如意码农
生活随笔 收集整理的這篇文章主要介紹了 Vue3+Ts笔记:基于element-UI 实现下拉框滚动翻页查询通用组件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

element 提供了 el-select組件,并且支持遠程搜索,但是對于數據量大需要翻頁的場景并未提供相應配置,所以自己寫了一個通用組件,作為記錄

初始化控件,定義傳入參數

將遠程查詢的接口封裝為函數,作為參數傳入組件,可以適應多種場景

<script lang="ts" setup>
import { nextTick, onMounted, ref, watch } from 'vue';
import { message } from "@/utils/message"; interface FetchParams {//遠程搜索使用的參數
[key: string]: any;
} const props = defineProps({
fetchData: {//傳入進行查詢的接口
type: Function,
required: true
},
modelValue: {//select 組件綁定的值
type: [String, Number],
default: ''
},
name: {//下拉框無對應選項的時候用于填充到選項里的值
type: String,
default: ''
},
placeholder: String,
disabled: Boolean,
param: {//查詢接口調用的參數
type: Object,
default: () => ({})
}
});

調用傳入函數獲取遠程數據

對傳入函數的基本調用以及一些異常處理,loading的值是el-select的配置項,這里需要注意的是在配置了loading = true時,刷新下拉框會內容時會明顯看到選項閃爍一下,如果不希望展示搜索刷新的效果,就不要配置loading

const getData = async (params: FetchParams, isLoadMore = false) => {
if (!hasMore.value && isLoadMore) return; loading.value = true;
try {
const res = await props.fetchData(params);
if (!res.error) {
const newItems = res.items?.map(item => ({
label: item.name,
value: item.id
})) || []; if (isLoadMore) {
// 加載更多時,追加數據
itemList.value = [...itemList.value, ...newItems];
} else {
// 首次加載或搜索時,替換數據
itemList.value = newItems;
} // 如果有 name 值,確保它在列表中
if (props.name && value.value) {
const existingItem = itemList.value.find(item => item.value === value.value);
if (!existingItem) {
itemList.value = [{
label: props.name,
value: value.value
}, ...itemList.value];
}
} // 判斷是否還有更多數據
hasMore.value = newItems.length === params.MaxResultCount;
totalItems.value = itemList.value.length;
} else {
// 如果接口返回錯誤,清空數據
itemList.value = [];
hasMore.value = false;
totalItems.value = 0;
}
} catch (error) {
// 如果發生錯誤,清空數據
itemList.value = [];
hasMore.value = false;
totalItems.value = 0;
message(error, { customClass: 'el', type: 'error' });
} finally {
loading.value = false;
}
};

遠程搜索方法

// 遠程搜索方法
const remoteSearch = debounce(async (query: string) => {
currentPage.value = 1; // 重置頁碼
hasMore.value = true; // 重置加載更多狀態
if (query) {
const params: FetchParams = {
...props.param,
skipCount: 1,
MaxResultCount: 10,
keyword: query
};
await getData(params);
} else {
// 如果搜索詞為空,則加載初始數據
const params: FetchParams = {
...props.param,
skipCount: 1,
MaxResultCount: 10
};
await getData(params);
}
}, 300);

下拉滾動事件監聽

這里就是最坑的地方了,因為el-select組件被封裝過,所以@scroll.native不會有任何效果。為了實現下拉框的滾動加載功能,只能用@visible-change 來監聽下拉框,并在下拉框狀態變化的時候添加下拉滾動事件

const handleVisibleChange = async (visible) => {
if (visible) {
// 先清空數據
itemList.value = [];
totalItems.value = 0;
hasMore.value = true;
currentPage.value = 1; // 加載初始數據
const params: FetchParams = {
...props.param,
skipCount: 1,
MaxResultCount: 10
};
await getData(params); // 添加滾動事件監聽
const dropdown = document.querySelector('.myselect-loadmore .el-select-dropdown__wrap');
if (dropdown) {
dropdown.addEventListener('scroll', handleScroll);
// 重置滾動位置
dropdown.scrollTop = 0;
}
} else {
// 移除滾動事件監聽
const dropdown = document.querySelector('.el-select-dropdown');
if (dropdown) {
dropdown.removeEventListener('scroll', handleScroll);
}
}
}; //防抖函數
function debounce<T extends (...args: any[]) => any>(func: T, delay: number) {
let timeout: NodeJS.Timeout;
return function (this: any, ...args: Parameters<T>) {
const context = this;
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(context, args), delay);
};
} const handleScroll = debounce(async (event) => {
// 判斷是否滾動到底部
const bottom = event.target.scrollHeight === event.target.scrollTop + event.target.clientHeight;
if (bottom && !loading.value && hasMore.value) {
currentPage.value++;
// 調用父組件傳遞的函數,并傳入子組件的參數
const params: FetchParams = {
...props.param,
skipCount: currentPage.value,
MaxResultCount: 10
};
await getData(params, true);
}
}, 100);

el-select 組件配置

popper-class的設置是為了讓事件能夠準確綁定到下拉框,不添加該屬性可能導致事件被綁定到父組件上面

<template>
<el-select
v-model="value"
class="myselect"
:placeholder="placeholder || '請選擇!'"
popper-class="myselect-loadmore"
filterable
remote
remote-show-suffix
:remote-method="remoteSearch"
clearable
:disabled="disabled"
@visible-change="handleVisibleChange"
@update:modelValue="(val) => emit('update:modelValue', val)">
<el-option v-for="(item, index) in itemList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>

父組件調用示例

              <SelectCommon v-model="Id" :fetch-data="getList" :param="selectParams"
placeholder="請選擇" />

適用于Vue3+ts+element的場景,組件完整代碼已經上傳至github,文件添加到項目可以直接調用。

地址:https://github.com/LearnerPing/SelectCommon.git

如果你覺得還算好用,請在github上面給我點個star

總結

以上是生活随笔為你收集整理的Vue3+Ts笔记:基于element-UI 实现下拉框滚动翻页查询通用组件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 成人黄色一级 | 天堂av2018 | 亚洲另类天堂 | 午夜精品福利在线观看 | 国产精品美女久久久久久久久 | 第一区免费在线观看 | 精品一区二区人妻 | 日本亲与子乱ay中文 | 黄色网日本| 超碰123 | 久久精品综合视频 | 国内精品在线观看视频 | 少妇高潮一区二区三区在线 | 欧美人与性动交α欧美精品 | 亚洲一区av在线 | 一级片视频网站 | 亚洲一区二区三区网站 | 久久国产精品久久久 | 乱色专区 | 91麻豆精品国产91久久久久久久久 | 久久综合国产精品 | 一级看片免费视频 | 丝袜亚洲综合 | 亚洲一区在线视频观看 | 欧美一级不卡 | 岛国精品资源网站 | 不用播放器av | 精品动漫一区二区三区在线观看 | 黄色毛毛片 | 欧美夫妇交换xxx | 午夜在线看片 | 国产偷v国产偷v亚洲高清 | 大桥未久恸哭の女教师 | 69av视频在线 | 韩国伦理在线 | 欧美色99 | 国产图片区| 免费av视屏 | 天天操天天看 | 亚洲国产av一区二区三区 | 一区二区三区少妇 | 欧美乱妇狂野欧美在线视频 | 精品久久人人 | 美女黄色一级视频 | 青青免费视频 | 四虎精品久久 | 久久人人看| 国产亚洲精品久久久久久无几年桃 | 蜜桃av在线看 | 久久va| 久久人妻无码aⅴ毛片a片app | 别揉我奶头一区二区三区 | 亚洲精品中文字幕在线 | 高清乱码毛片入口 | 日韩一级精品 | 久草五月 | 最新黄色网址在线观看 | 精品国产一区二区三区性色av | 天堂毛片 | 一级免费黄色大片 | 国产最新精品 | 天堂网一区二区三区 | 黑人精品一区二区 | 精品国产丝袜一区二区三区乱码 | 一区二区国产精品 | 91丝袜一区二区三区 | 夜间福利在线 | 极品少妇xxxx精品少妇偷拍 | 在线观看欧美一区 | 欧美区在线 | 久久久黄色网 | 在线免费观看麻豆 | 成人免费毛片日本片视频 | 成人自拍视频在线 | 综合天堂av久久久久久久 | 亚洲AV无码一区二区三区少妇 | 欧美一级α片 | 一卡二卡三卡四卡五卡 | 老司机精品视频在线 | 午夜家庭影院 | 国产一区二区三区四区hd | 好看的av网址 | 久久久精品久久久 | 久久免费视屏 | 欧美中文字幕第一页 | 国产一区二区免费视频 | 奇米激情 | 毛片在哪里看 | www.日批 | 五月天婷婷综合网 | 日韩免费观看一区二区三区 | 熟女一区二区三区四区 | 宅男午夜影院 | 日韩av在线一区二区 | 8x国产一区二区三区精品推荐 | 肥熟女一区二区三肥熟女 | 国产精品美女在线观看 | 在线观看你懂的网址 | 播播成人网 |