当前位置:首页 > 问答 > 正文

前端开发 数据展示 vue分页、vue分页器组件实现与使用详解

前端开发 数据展示 vue分页、vue分页器组件实现与使用详解

🚀 Vue分页器组件实现与使用详解(2025最新版)

在大数据量场景下,分页器是提升用户体验的关键组件!通过本文,你将掌握Vue3分页器的完整实现流程,包括后端交互、动态页码生成等核心技巧,并附上2025年最新代码示例!💡

🔧 核心实现步骤

1️⃣ 数据源与分页参数设置

// 主组件数据
data() {
  return {
    items: [],       // 数据源
    currentPage: 1,  // 当前页码
    itemsPerPage: 10, // 每页条数
    totalItems: 100, // 总数据量
    continues: 5     // 连续页码数
  }
}

2️⃣ 创建分页组件(🛠️ 组件化封装)

<!-- Pagination.vue -->
<template>
  <div class="pagination">
    <button @click="prevPage" :disabled="currentPage === 1">上一页</button>
    <span v-if="start > 1">1...</span>
    <button 
      v-for="page in pageList" 
      :key="page"
      @click="handlePage(page)"
      :class="{ active: page === currentPage }"
    >
      {{ page }}
    </button>
    <span v-if="end < totalPages">...</span>
    <button @click="nextPage" :disabled="currentPage === totalPages">下一页</button>
  </div>
</template>
<script setup>
import { computed } from 'vue';
const props = defineProps({
  totalItems: Number,
  itemsPerPage: Number,
  currentPage: Number,
  continues: { type: Number, default: 5 }
});
const totalPages = computed(() => Math.ceil(props.totalItems / props.itemsPerPage));
const pageList = computed(() => {
  const half = Math.floor(props.continues / 2);
  let start = props.currentPage - half;
  let end = props.currentPage + half;
  // 边界处理
  if (start < 1) { start = 1; end = props.continues; }
  if (end > totalPages.value) { end = totalPages.value; start = end - props.continues + 1; }
  return Array.from({length: end - start + 1}, (_,i) => start + i);
});
</script>

3️⃣ 处理分页逻辑(🧠 智能页码计算)

// 主组件方法
const handlePageChange = (page) => {
  currentPage.value = page;
  fetchData(); // 触发数据重新加载
};
// 计算属性示例
const paginatedItems = computed(() => {
  const start = (currentPage.value - 1) * itemsPerPage.value;
  const end = start + itemsPerPage.value;
  return items.value.slice(start, end);
});

4️⃣ 与后端API交互(📡 实战数据加载)

// 使用Axios请求分页数据
const fetchData = async () => {
  try {
    const response = await axios.get('/api/data', {
      params: {
        page: currentPage.value,
        pageSize: itemsPerPage.value
      }
    });
    items.value = response.data.items;
    totalItems.value = response.data.total;
  } catch (error) {
    console.error('数据加载失败', error);
  }
};

🚀 高级技巧

1️⃣ 动态页码生成(🔄 智能省略号)

// 计算连续页码范围
const calculatePageRange = () => {
  if (totalPages.value <= continues.value) return Array.from({length: totalPages.value}, (_,i) => i+1);
  const half = Math.floor(continues.value / 2);
  let start = currentPage.value - half;
  let end = currentPage.value + half;
  if (start < 1) { start = 1; end = continues.value; }
  if (end > totalPages.value) { end = totalPages.value; start = end - continues.value + 1; }
  return [1, '...', ...Array.from({length: end - start + 1}, (_,i) => start + i), '...', totalPages.value];
};

2️⃣ 性能优化(⚡ 虚拟滚动)

<!-- 虚拟滚动分页 -->
<template>
  <div class="virtual-scroll">
    <div 
      v-for="item in visibleItems" 
      :key="item.id"
      :style="{ transform: `translateY(${item.index * itemHeight}px)` }"
    >
      {{ item.content }}
    </div>
  </div>
</template>script setup>
const itemHeight = 40; // 每项高度
const visibleCount = Math.ceil(window.innerHeight / itemHeight);
const visibleItems = computed(() => {
  const start = (currentPage.value - 1) * itemsPerPage.value;
  const end = start + visibleCount;
  return items.value.slice(start, end);
});
</script>

🧩 使用现有组件库(快速上手)

Element Plus 分页组件

<template>
  <el-pagination
    @current-change="handleCurrentChange"
    :current-page="currentPage"
    :page-size="itemsPerPage"
    :total="totalItems"
    layout="total, sizes, prev, pager, next, jumper"
  />
</template>
<script setup>
import { ref } from 'vue';
const currentPage = ref(1);
const itemsPerPage = ref(10);
const totalItems = ref(100);
const handleCurrentChange = (page) => {
  currentPage.value = page;
  fetchData();
};
</script>

💻 完整示例代码

<template>
  <div>
    <ul>
      <li v-for="item in paginatedItems" :key="item.id">{{ item.name }}</li>
    </ul>
    <Pagination
      :total-items="totalItems"
      :items-per-page="itemsPerPage"
      :current-page="currentPage"
      @page-changed="handlePageChange"
    />
  </div>
</template>
<script setup>
import { ref, computed } from 'vue';
import Pagination from './components/Pagination.vue';
import axios from 'axios';
const items = ref([]);
const currentPage = ref(1);
const itemsPerPage = ref(10);
const totalItems = ref(100);
const paginatedItems = computed(() => {
  const start = (currentPage.value - 1) * itemsPerPage.value;
  const end = start + itemsPerPage.value;
  return items.value.slice(start, end);
});
const fetchData = async () => {
  const response = await axios.get('/api/data', {
    params: { page: currentPage.value, pageSize: itemsPerPage.value }
  });
  items.value = response.data.items;
  totalItems.value = response.data.total;
};
const handlePageChange = (page) => {
  currentPage.value = page;
  fetchData();
};
</script>

通过本文,你已掌握:

  • ✅ 后端分页与前端分页的权衡
  • ✅ 动态页码生成算法
  • ✅ 与API的无缝交互
  • ✅ 组件化封装最佳实践
  • ✅ 性能优化技巧(虚拟滚动)

立即实践,让你的数据展示体验飞起来!🚀

前端开发 数据展示 vue分页、vue分页器组件实现与使用详解

发表评论