Vue 分页实现方法

在 Vue 中实现分页功能有几种常见方法,下面介绍几种主要的实现方式:

1. 使用 Element UI 的分页组件

如果你使用 Element UI 组件库,可以很方便地使用其分页组件:

<template>
  <div>
    <!-- 表格数据展示 -->
    <el-table :data="currentPageData" style="width: 100%">
      <!-- 表格列定义 -->
    </el-table>
    <!-- 分页组件 -->
    <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>
  </div>
</template>


<script>
export default {
  data() {
    return {
      allData: [], // 所有数据
      currentPageData: [], // 当前页数据
      currentPage: 1, // 当前页码
      pageSize: 10, // 每页条数
      totalItems: 0 // 总条数
    }
  },
  created() {
    this.fetchData();
  },
  methods: {
    fetchData() {
      // 模拟获取数据
      // 实际项目中可能是 API 请求
      this.allData = Array.from({length: 100}, (_, i) => ({ id: i + 1, name: `Item ${i + 1}` }));
      this.totalItems = this.allData.length;
      this.updateCurrentPageData();
    },
    updateCurrentPageData() {
      const start = (this.currentPage - 1) * this.pageSize;
      const end = start + this.pageSize;
      this.currentPageData = this.allData.slice(start, end);
    },
    handleSizeChange(val) {
      this.pageSize = val;
      this.updateCurrentPageData();
    },
    handleCurrentChange(val) {
      this.currentPage = val;
      this.updateCurrentPageData();
    }
  }
}
</script>

2. 自定义分页组件

如果不使用 UI 库,可以自己实现分页:

<template>
  <div>
    <ul>
      <li v-for="item in currentPageData" :key="item.id">
        {{ item.name }}
      </li>
    </ul>

    <div class="pagination">
      <button 
        @click="prevPage" 
        :disabled="currentPage === 1">
        上一页
      </button>

      <span v-for="page in totalPages" :key="page">
        <button 
          @click="goToPage(page)"
          :class="{ active: currentPage === page }">
          {{ page }}
        </button>
      </span>

      <button 
        @click="nextPage" 
        :disabled="currentPage === totalPages">
        下一页
      </button>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      allData: [],
      currentPageData: [],
      currentPage: 1,
      pageSize: 10
    }
  },
  computed: {
    totalPages() {
      return Math.ceil(this.allData.length / this.pageSize);
    }
  },
  created() {
    this.fetchData();
  },
  methods: {
    fetchData() {
      // 模拟数据
      this.allData = Array.from({length: 100}, (_, i) => ({ id: i + 1, name: `Item ${i + 1}` }));
      this.updateCurrentPageData();
    },
    updateCurrentPageData() {
      const start = (this.currentPage - 1) * this.pageSize;
      const end = start + this.pageSize;
      this.currentPageData = this.allData.slice(start, end);
    },
    prevPage() {
      if (this.currentPage > 1) {
        this.currentPage--;
        this.updateCurrentPageData();
      }
    },
    nextPage() {
      if (this.currentPage < this.totalPages) {
        this.currentPage++;
        this.updateCurrentPageData();
      }
    },
    goToPage(page) {
      this.currentPage = page;
      this.updateCurrentPageData();
    }
  }
}
</script>

<style>
.pagination button {
  margin: 0 5px;
}
.pagination button.active {
  font-weight: bold;
  color: blue;
}
</style>

3. 后端分页(API 分页)

实际项目中,通常数据量较大,需要后端分页:

<template>
  <div>
    <el-table :data="tableData" style="width: 100%">
      <!-- 表格列定义 -->
    </el-table>

    <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="total">
    </el-pagination>
  </div>
</template>

<script>
import axios from 'axios';

export default {
  data() {
    return {
      tableData: [],
      currentPage: 1,
      pageSize: 10,
      total: 0
    }
  },
  created() {
    this.fetchData();
  },
  methods: {
    async fetchData() {
      try {
        const response = await axios.get('/api/items', {
          params: {
            page: this.currentPage,
            size: this.pageSize
          }
        });
        this.tableData = response.data.items;
        this.total = response.data.total;
      } catch (error) {
        console.error('获取数据失败:', error);
      }
    },
    handleSizeChange(val) {
      this.pageSize = val;
      this.fetchData();
    },
    handleCurrentChange(val) {
      this.currentPage = val;
      this.fetchData();
    }
  }
}
</script>

注意事项

对于大数据量,推荐使用后端分页,减少前端压力
分页组件通常需要显示总条数、每页条数选择、页码跳转等功能
可以添加加载状态,在数据请求时显示加载动画
考虑添加页码输入框,方便用户快速跳转到指定页
以上是 Vue 中实现分页的几种常见方法,你可以根据项目需求选择适合的方式。