Appearance
Vue 分页(服务端)
服务端模式(靠 manualPagination: true 开启):表格只渲染分页器 + 派发 onPageChange,不做任何数据切片。在回调里按页取数后 setList + setTotal 回填。
示例用本地 200 条数据模拟「服务端」,真实项目里换成接口请求即可。想让表格自己切片见分页(客户端)。
使用的 API
ts
type Options = {
list: T[]; // 当前页数据(首屏)
itemKey: string; // 行唯一标识字段名
estimatedSize: number; // 行预估高度(px)
manualPagination: true; // 关掉表格自己的切片
pagination: {
total: number;
page?: number;
pageSize: number;
pageSizes?: number[];
};
onPageChange?: (page: number, pageSize: number) => void;
}
// 回调里回填(ref 上调用)
tableRef.value?.setList(fetchPage(page, pageSize));
tableRef.value?.setTotal(total);注意
onPageChange 里要拿 ref 调 setList,所以 tableRef 需在 options 之前声明——示例里就是这个顺序。
完整语义(与排序筛选的组合、竞态处理、和 dataMode: 'server' 的区别)见 Vanilla · 分页(服务端)。
示例
微应用尚未挂载。
源码
点击查看源码
vue
<template>
<div class="demo-wrapper">
<h3 class="demo-title">Vue 分页(服务端)</h3>
<div class="demo-hint">
服务端模式(manualPagination: true):表格只渲染分页器并派发 onPageChange,不做数据切片。
翻页/跳页/切换每页条数时,在回调里按页取数后 setList + setTotal。想让表格自己切片见「分页(客户端)」示例。
</div>
<div style="width: 820px; height: 520px" class="demo-container">
<VirtTableVue ref="tableRef" :columns="columns" :options="options" />
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { VirtTableVue, type VueTableColumn } from '@virt-table/vue';
import { faker } from '@faker-js/faker';
import type { VirtTableVueInstance } from '../../virt-table-ref';
/**
* 分页示例(**服务端模式**,靠 manualPagination 开启):表格只渲染分页器 + 派发 onPageChange,
* 不做任何数据切片。这里用本地 200 条数据模拟「服务端」,在 onPageChange
* 回调里按页切片再 setList,并 setTotal 回填总数——真实项目里换成接口请求即可。
*/
interface Row extends Record<string, unknown> {
id: number;
name: string;
dept: string;
qty: number;
price: number;
}
const depts = ['工程部', '设计部', '市场部', '财务部'];
const columns: VueTableColumn<Row>[] = [
{ key: 'id', title: 'ID', width: 80, sortable: true },
{ key: 'name', title: '姓名', width: 220 },
{ key: 'dept', title: '部门', width: 160 },
{ key: 'qty', title: '数量', width: 140, align: 'right' },
{ key: 'price', title: '单价', width: 140, align: 'right' },
];
// 模拟服务端数据源(真实场景中在后端)
const TOTAL = 200;
const db: Row[] = Array.from({ length: TOTAL }, (_, i) => ({
id: i + 1,
name: faker.person.fullName(),
dept: depts[i % depts.length]!,
qty: faker.number.int({ min: 1, max: 20 }),
price: faker.number.int({ min: 5, max: 500 }),
}));
// 模拟「服务端」按页取数
const fetchPage = (page: number, pageSize: number): Row[] => {
const start = (page - 1) * pageSize;
return db.slice(start, start + pageSize);
};
const initialPageSize = 20;
const tableRef = ref<VirtTableVueInstance | null>(null);
const options = {
list: fetchPage(1, initialPageSize),
itemKey: 'id',
estimatedSize: 40,
buffer: 6,
border: true,
// 不开这个就是默认的客户端分页(表格自己切片),见 feature/pagination-client
manualPagination: true,
pagination: {
total: TOTAL,
page: 1,
pageSize: initialPageSize,
pageSizes: [10, 20, 50, 100],
},
onPageChange: (page: number, pageSize: number) => {
// 真实项目:此处发起接口请求,拿到当前页数据与总数后回填
tableRef.value?.setList(fetchPage(page, pageSize));
tableRef.value?.setTotal(TOTAL);
},
};
</script>