vue2和vue3上拉加载更多示例代码
Vue2
html
<template>
<div>
<ul
class="list"
v-infinite-scroll="loadMore"
infinite-scroll-disabled="busy"
infinite-scroll-immediate-check="false"
>
<li
v-for="(item, index) in studentData"
class="addLi"
:key="index"
>
<div class="ellipsis-container">姓名:{{ item.name }}</div>
<p style="width: 33%; text-align: center">
{{ item.phone_no }}
</p>
<div
style="
width: 28%;
display: flex;
justify-content: flex-start;
align-items: left;
"
>
<span>设备:</span>
<div>
<el-link
type="primary"
v-if="item.sensor.length === 0"
:underline="false"
@click="bindStu(item)"
>去绑定</el-link
>
<div v-else>
<span v-if="item.sensor.hr_sensor_sn">{{ item.sensor.hr_sensor_sn }}</span>
<span v-if="item.sensor.private_hr_sensor_sn">{{ item.sensor.private_hr_sensor_sn }}(私有)</span>
</div>
</div>
</div>
</li>
</ul>
<p v-if="loading" style="text-align: center">加载中...</p>
<p v-if="noMore" style="text-align: center">没有更多了</p>
</div>
</template>
<script>
export default {
data() {
return {
studentData: [], // 学生数据列表
loading: false, // 是否正在加载数据
noMore: false, // 是否没有更多数据
page: 1, // 当前页码
limit: 10, // 每页显示的数据条数
totalPages: 5, // 总页数
};
},
computed: {
busy() {
// 计算属性,用于控制无限滚动是否可用
return this.loading || this.noMore;
},
},
methods: {
loadMore() {
if (this.noMore || this.page > this.totalPages) return;
this.loading = true;
// 模拟异步请求数据
setTimeout(() => {
const newData = this.generateData(this.page, this.limit);
if (newData.length < this.limit || this.page >= this.totalPages) {
this.noMore = true; // 如果数据不足limit,则表示没有更多数据
}
this.studentData = this.studentData.concat(newData);
this.page++;
this.loading = false;
}, 1000);
},
generateData(page, limit) {
// 模拟生成数据
const data = [];
for (let i = 0; i < limit; i++) {
const index = (page - 1) * limit + i;
data.push({
name: `学生${index}`,
phone_no: `13800000000${index}`,
sensor: [],
hr_sensor_sn: `SN${index}`,
private_hr_sensor_sn: `PSN${index}`,
});
}
return data;
},
bindStu(item) {
// 绑定学生事件处理
console.log('绑定学生:', item);
},
},
mounted() {
this.loadMore(); // 初始加载数据
},
};
</script>
<style scoped>
.list {
list-style: none;
padding: 0;
}
.addLi {
padding: 10px;
border-bottom: 1px solid #eee;
}
.ellipsis-container {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>
Vue3
vue3不支持v-infinite-scroll指令,需要安装一个插件,如下:
安装模块
js
npm install vue3-infinite-scroll-good
在main.js
注册指令
js
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import VueInfiniteScroll from 'vue3-infinite-scroll-good'; // 引入
const app = createApp(App)
app.directive('infinite-scroll', VueInfiniteScroll); // 注册指令
app.use(ElementPlus)
app.mount('#app')
具体页面代码如下:
html
<template>
<div>
<ul
class="list"
v-infinite-scroll="loadMore"
infinite-scroll-disabled="busy"
infinite-scroll-immediate-check="false"
>
<li
v-for="(item, index) in studentData"
class="addLi"
:key="index"
>
<div class="ellipsis-container">姓名:{{ item.name }}</div>
<p style="width: 33%; text-align: center">
{{ item.phone_no }}
</p>
<div
style="
width: 28%;
display: flex;
justify-content: flex-start;
align-items: left;
"
>
<span>设备:</span>
<div>
<el-link
type="primary"
v-if="item.sensor.length === 0"
:underline="false"
@click="bindStu(item)"
>去绑定</el-link
>
<div v-else>
<span v-if="item.sensor.hr_sensor_sn">{{ item.sensor.hr_sensor_sn }}</span>
<span v-if="item.sensor.private_hr_sensor_sn">{{ item.sensor.private_hr_sensor_sn }}(私有)</span>
</div>
</div>
</div>
</li>
</ul>
<p v-if="loading" style="text-align: center">加载中...</p>
<p v-if="noMore" style="text-align: center">没有更多了</p>
</div>
</template>
<script setup>
import { ref, reactive, computed, onMounted } from 'vue';
import { ElLink } from 'element-plus';
const studentData = ref([]); // 学生数据列表
const loading = ref(false); // 是否正在加载数据
const noMore = ref(false); // 是否没有更多数据
const page = ref(1); // 当前页码
const limit = ref(10); // 每页显示的数据条数
const totalPages = ref(5); // 总页数
const busy = computed(() => loading.value || noMore.value);
function loadMore() {
if (noMore.value || page.value > totalPages.value) return;
loading.value = true;
// 模拟异步请求数据
setTimeout(() => {
const newData = generateData(page.value, limit.value);
if (newData.length < limit.value || page.value >= totalPages.value) {
noMore.value = true; // 如果数据不足limit,则表示没有更多数据
}
studentData.value = [...studentData.value, ...newData];
page.value++;
loading.value = false;
}, 1000);
}
function generateData(page, limit) {
// 模拟生成数据
const data = [];
for (let i = 0; i < limit; i++) {
const index = (page - 1) * limit + i;
data.push({
name: `学生${index}`,
phone_no: `13800000000${index}`,
sensor: [],
hr_sensor_sn: `SN${index}`,
private_hr_sensor_sn: `PSN${index}`,
});
}
return data;
}
function bindStu(item) {
// 绑定学生事件处理
console.log('绑定学生:', item);
}
onMounted(() => {
loadMore(); // 初始加载数据
});
</script>
<style scoped>
.list {
list-style: none;
padding: 0;
}
.addLi {
padding: 10px;
border-bottom: 1px solid #eee;
}
.ellipsis-container {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>