Skip to content
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>