版本:vue.js elementui2.15.6
实现效果:滑动下拉菜单时,自动请求数据库数据
核心思路:对下拉菜单div的scroll事件进行监听,事件触发时发送请求
html
<template>
<div id="SelectSearchPage" class="infinite-scroll-select">
<span>功能名称或需求列表:</span>
<!--popper-class定义下拉框class,方便获取div-->
<el-select v-model="selectedValue" placeholder="请选择" filterable remote :loading="loading" clearable style="width: 300px;" ref="mySelect"
@visible-change="handleVisibleChange"
@change="change"
:remote-method="handleSearch"
popper-class="select-search-page-dropdown-popper"
>
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</div>
</template>
注意:popper-class="select-search-page-dropdown-popper"定义下拉框class,方便取DIV,否则同时有多个下拉展示时不知道数据那个下拉。
javascript
import message from 'element-ui/packages/message'
export default {
name: 'SelectSearchPage',
props: {
},
data() {
return {
selectedValue: '',
options: [],
loading: false,
loadingMore: false,
// 分页参数
page: 1,
pageSize: 10,
total: 0,
hasMore: true,
keyword: '',
scrollListener: null
};
},
mounted() {
this.requestData('',true)
},
methods: {
// 加载数据
async requestData(queryValue,resetPage = true) {
if (resetPage) {
this.page = 1;
this.hasMore = true;
this.loading = true;
} else {
this.loadingMore = true;
}
try {
const params = {
pageNo: this.page,
pageSize: this.pageSize,
name: queryValue
};
const response = await findNameList(params);
if(response.code===200){
const data = response.data
if (resetPage) {
this.options = data.records;
} else {
this.options = [...this.options, ...data.records];
}
this.total = data.total;
this.hasMore = this.page * this.pageSize < data.total;
}
} catch (error) {
console.error('加载失败:', error);
} finally {
this.loading = false;
this.loadingMore = false;
}
},
change(){
this.$emit("change",this.selectedValue);
},
handleVisibleChange(visible){
// const selectSearchPage = document.getElementById("SelectSearchPage");
const dom = document.querySelector(".select-search-page-dropdown-popper").querySelector(".el-scrollbar").querySelector(".el-scrollbar__wrap")
if(!visible){
dom.removeEventListener("scroll",this.scrollEvent);
}
dom.addEventListener("scroll",this.scrollEvent)
},
scrollEvent(event){
// console.log('滑动事件被触发,',event);
const domTarget =event.target
const scrollTop = domTarget.scrollTop
const clientHeight =domTarget.clientHeight
const scrollHeight = domTarget.scrollHeight
const scrollBottom = scrollHeight - clientHeight - scrollTop;
console.log('scrollTop: ',scrollTop,',clientHeight:',clientHeight,',scrollHeight:',scrollHeight,',距离底部距离:',(scrollHeight - clientHeight - scrollTop));
if(scrollBottom <=20){
this.page++;
if(this.hasMore) {
this.requestData(this.keyword, false)
}else{
message({ message: `数据已加载完毕`, type: 'success', })
}
}
},
// 搜索
handleSearch(query) {
this.keyword = query
this.requestData(query,true);
},
}
}
