如何使用VueJS实现表格分页并支持自定义每页展示条数
Vue实现表格分页及每页条数自定义方案
1. 核心逻辑说明
- 把全量表格数据存为Vue响应式变量,不直接全量渲染
- 通过计算属性根据「当前页码」和「每页展示条数」动态截取对应区间的数据渲染到表格
- 切换每页条数时自动重置页码为第1页,避免出现页码越界问题
如果你使用的是Vue2,只需将下述响应式数据定义放到组件的
data配置项中,计算属性放到computed配置项,方法放到methods配置项即可,逻辑完全一致。
2. 核心逻辑代码(Vue3组合式API)
import { ref, computed } from 'vue' // 全量表格数据,实际场景可从接口获取 const tableData = ref([ { id: 1, name: 'Sara', email: 'example1@example.com', time: '12/2/2021 16:40' }, { id: 2, name: 'Safa', email: 'example2@example.com', time: '24/2/2021 08:40' }, // 剩余业务数据自行补充 ]) // 当前页码,默认第一页 const currentPage = ref(1) // 每页展示条数,默认10 const pageSize = ref(10) // 可选每页条数配置 const pageSizeOptions = ref([10, 20, 50, 100]) // 计算属性:总页数 const totalPage = computed(() => Math.ceil(tableData.value.length / pageSize.value)) // 计算属性:当前页要展示的表格数据 const currentPageData = computed(() => { const start = (currentPage.value - 1) * pageSize.value const end = start + pageSize.value return tableData.value.slice(start, end) }) // 计算属性:分页统计文本 const paginationText = computed(() => { const start = (currentPage.value - 1) * pageSize.value + 1 const end = Math.min(currentPage.value * pageSize.value, tableData.value.length) return `Showing ${start} to ${end} out of ${tableData.value.length}` }) // 切换页码方法 const changePage = (page) => { if (page < 1 || page > totalPage.value) return currentPage.value = page } // 切换每页条数方法 const changePageSize = (e) => { pageSize.value = Number(e.target.value) // 切换每页条数后重置到第一页 currentPage.value = 1 }
3. 模板改造代码
保留原有Bootstrap样式,替换静态HTML为以下动态绑定模板:
<!-- 新增每页条数选择器 --> <div class="mb-3 d-flex align-items-center"> <span class="me-2">每页展示:</span> <select class="form-select w-auto" @change="changePageSize" :value="pageSize"> <option v-for="size in pageSizeOptions" :key="size" :value="size">{{ size }}条</option> </select> </div> <!-- 表格部分 --> <table class="table table-bordered" id="dataTable" width="100%" cellspacing="0"> <thead> <tr> <th>#</th> <th>Name</th> <th>Email</th> <th>Date & Time</th> </tr> </thead> <tbody> <tr v-for="item in currentPageData" :key="item.id"> <td>{{ item.id }}</td> <td>{{ item.name }}</td> <td>{{ item.email }}</td> <td>{{ item.time }}</td> </tr> </tbody> </table> <!-- 分页栏部分 --> <div class="row"> <div class="col-4"> {{ paginationText }} </div> <div class="col-8 text-end"> <div class="btn-group" role="group" aria-label="Pagination"> <!-- 上一页按钮 --> <button type="button" class="btn btn-outline-primary" @click="changePage(currentPage - 1)" :disabled="currentPage === 1" > 上一页 </button> <!-- 页码按钮 --> <button v-for="page in totalPage" :key="page" type="button" class="btn btn-outline-primary" :class="{ active: page === currentPage }" @click="changePage(page)" > {{ page }} </button> <!-- 下一页按钮 --> <button type="button" class="btn btn-outline-primary" @click="changePage(currentPage + 1)" :disabled="currentPage === totalPage" > 下一页 </button> </div> </div> </div>
4. 可选优化
如果总页数过多,可调整页码渲染逻辑,只展示当前页前后2个页码+首尾页,避免分页栏过长。
内容的提问来源于stack exchange,提问作者Safaa
相关产品推荐
相关产品推荐

