vue2下拉分页
<template>
<div>
<el-select v-model="selected" placeholder="请选择" @visible-change="handleDropdownVisibility">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<el-option
value="more"
disabled
@click.native.prevent="showDialog = true"
style="cursor: pointer;">
更多选项...
</el-option>
</el-select>
<el-dialog
title="选择选项"
:visible.sync="showDialog"
width="30%">
<div v-for="group in paginatedOptions" :key="group.page">
<p>第 {{ group.page }} 页</p>
<el-option
v-for="item in group.items"
:key="item.value"
:label="item.label"
:value="item.value"
@click="selectOption(item.value); showDialog = false;">
</el-option>
</div>
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="totalItems">
</el-pagination>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
selected: null,
showDialog: false,
currentPage: 1,
pageSize: 10,
totalItems: 100, // 假设总项数为100
allOptions: [], // 这里应该包含所有选项,通过API或其他方式加载
paginatedOptions: [], // 分页后的选项
};
},
computed: {
options() {
// 这里可以返回一些初始选项,或者空数组
return [];
},
},
methods: {
handleDropdownVisibility(val) {
// 如果需要的话,可以在这里处理下拉菜单的显示逻辑
// 但对于分页,我们主要依赖点击“更多选项...”
},
showDialogOptions() {
// 根据当前页和每页数量计算分页选项
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
this.paginatedOptions = [
{ page: this.currentPage, items: this.allOptions.slice(start, end) }
];
// 如果需要支持多页预览,可以修改此逻辑来包含多页
},
handleSizeChange(val) {
this.pageSize = val;
this.currentPage = 1; // 当改变每页数量时,重置到第一页
this.showDialogOptions();
},
handleCurrentChange(val) {
this.currentPage = val;
this.showDialogOptions();
},
selectOption(value) {
this.selected = value;
},
// 假设在某个地方加载了所有选项
loadAllOptions() {
// 模拟从API加载数据
this.allOptions = Array.from({ length: 100 }, (_, i) => ({
value: i,
label: `选项 ${i + 1}`
}));
this.totalItems = this.allOptions.length;
},
// 在组件创建或需要时调用
mounted() {
this.loadAllOptions();
}
},
};
</script>
vue2下拉懒加载
<template>
<div>
<el-select v-model="selected" placeholder="请选择" ref="select">
<el-option
v-for="item in visibleOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
<el-option
disabled
@click.native.prevent="showPopover = true"
slot="prepend"
style="cursor: pointer;">
请选择...
</el-option>
</el-select>
<el-popover
placement="bottom"
width="100%"
trigger="manual"
v-model="showPopover"
popper-class="select-popover"
@before-leave="handleBeforeLeave">
<div
class="select-dropdown"
@scroll="handleScroll"
ref="dropdown">
<el-option
v-for="item in allOptions.slice(0, loadedCount)"
:key="item.value"
:label="item.label"
:value="item.value"
@click="selectOption(item.value); showPopover = false;">
</el-option>
</div>
</el-popover>
</div>
</template>
<script>
export default {
data() {
return {
selected: null,
showPopover: false,
allOptions: [], // 假设这里有一千条数据
visibleOptions: [], // 用于el-select的初始选项(可以留空或放几个引导选项)
loadedCount: 0, // 已加载的选项数量
pageSize: 20, // 每页加载数量
};
},
methods: {
// 假设在某个地方加载了所有选项
loadAllOptions() {
// 模拟从API加载数据
this.allOptions = Array.from({ length: 1000 }, (_, i) => ({
value: i,
label: `选项 ${i + 1}`
}));
},
handleScroll(event) {
const target = event.target;
const scrollDistance = target.scrollHeight - target.scrollTop - target.clientHeight;
if (scrollDistance < 10) { // 接近底部时加载更多
this.loadMoreOptions();
}
},
loadMoreOptions() {
const newCount = Math.min(this.loadedCount + this.pageSize, this.allOptions.length);
this.loadedCount = newCount;
},
selectOption(value) {
this.selected = value;
// 可能需要做一些额外的处理,比如关闭下拉列表
},
handleBeforeLeave() {
// 在关闭popover前可能需要的处理
},
// 在组件创建或需要时调用
mounted() {
this.loadAllOptions();
this.loadedCount = this.pageSize; // 初始加载一定数量的选项
}
}
};
</script>
<style>
.select-popover .el-popover__wrap {
padding: 0;
}
.select-dropdown {
max-height: 300px; /* 设置最大高度以产生滚动 */
overflow-y: auto;
}
</style>
vue3下拉分页
<template>
<div>
<!-- 下拉列表 -->
<el-select v-model="selectedValue" placeholder="请选择" @change="handleChange">
<el-option
v-for="item in currentItems"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<!-- 分页组件 -->
<el-pagination
v-if="totalItems > pageSize"
layout="prev, pager, next"
:total="totalItems"
:page-size="pageSize"
:current-page="currentPage"
@current-change="handlePageChange"
/>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
// 模拟 API 获取数据
const fetchData = (page, pageSize) => {
return new Promise((resolve) => {
setTimeout(() => {
const total = 50; // 假设总数据量为 50
const items = Array.from({ length: pageSize }, (_, index) => ({
label: `选项 ${index + 1 + (page - 1) * pageSize}`,
value: index + 1 + (page - 1) * pageSize,
}));
resolve({ items, total });
}, 500);
});
};
// 设置响应式状态
const selectedValue = ref(null);
const currentPage = ref(1);
const pageSize = ref(10); // 每页显示的数量
const totalItems = ref(0);
const items = ref([]);
// 当前页的项目
const currentItems = computed(() => {
return items.value;
});
// 获取数据
const getData = async (page) => {
try {
const response = await fetchData(page, pageSize.value);
items.value = response.items;
totalItems.value = response.total;
} catch (error) {
ElMessage.error('数据加载失败');
}
};
// 页码改变时的处理函数
const handlePageChange = (page) => {
currentPage.value = page;
getData(page);
};
// 监听下拉列表选项变化
const handleChange = (value) => {
console.log('当前选中的值:', value);
};
// 初次加载数据
onMounted(() => {
getData(currentPage.value);
});
</script>
<style scoped>
/* 添加一些简单的样式 */
</style>
vue3下拉懒加载
//@scroll="handleScroll"----el-select没有监听滚动事件需要自行添加,并且为滚动添加防抖
// let select: any = document.querySelector(".el-select-dropdown__wrap");
// select.addEventListener("scroll", (event: any) => {
// console.log("滚动事件");
// let timer: any = null;
// if (timer) {
// clearTimeout(timer);
// }
// timer = setTimeout(() => {
// loadMoreData();
// }, 5000);
// });
<template>
<el-select v-model="selectedValue" placeholder="请选择" @scroll="handleScroll">
<el-option
v-for="item in items"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-option v-if="loading" disabled>加载中...</el-option>
</el-select>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import { ElMessage } from 'element-plus';
// 模拟 API 获取数据
const fetchLazyData = (page, pageSize) => {
return new Promise((resolve) => {
setTimeout(() => {
const total = 100; // 假设总数据量为 100
const items = Array.from({ length: pageSize }, (_, index) => ({
label: `选项 ${index + 1 + (page - 1) * pageSize}`,
value: index + 1 + (page - 1) * pageSize,
}));
resolve({ items, total });
}, 500);
});
};
// 设置响应式状态
const selectedValue = ref(null);
const items = ref([]);
const pageSize = ref(10);
const currentPage = ref(1);
const loading = ref(false);
const totalItems = ref(0);
// 获取数据
const loadMoreData = async () => {
if (loading.value || items.value.length >= totalItems.value) return;
loading.value = true;
try {
const response = await fetchLazyData(currentPage.value, pageSize.value);
items.value = [...items.value, ...response.items];
totalItems.value = response.total;
currentPage.value += 1;
} catch (error) {
ElMessage.error('加载失败');
} finally {
loading.value = false;
}
};
// 处理滚动懒加载
const handleScroll = (event) => {
const { target } = event;
if (target.scrollTop + target.clientHeight >= target.scrollHeight - 50) {
loadMoreData();
}
};
// 初次加载数据
onMounted(() => {
loadMoreData();
});
</script>
<style scoped>
/* 添加一些简单的样式 */
</style>