Skip to content

usePagination

一个分页状态管理 Hook,提供完整的分页功能,包括页码跳转、每页大小调整、分页信息计算等。支持响应式数据源和丰富的回调机制。

基础用法

📄 基础分页功能

基础分页

1 / 10
跳转到:
当前页: 1
每页大小: 10
总数据量: 95
总页数: 10
数据范围: 1 - 10

每页大小调整

每页显示:总共 127 条数据
...
当前显示: 第 1 - 10 条,共 127 条

数据表格示例

ID姓名邮箱状态
1张三zhangsan@example.com活跃
2李四lisi@example.com待激活
3王五wangwu@example.com活跃
4赵六zhaoliu@example.com活跃
5钱七qianqi@example.com待激活
显示第 1 - 5 条,共 12 条
1 / 3

高级用法

🚀 高级分页功能

响应式数据源

模拟数据量:
1 / 10
响应式总数: 150 条
当前页码: 1
总页数: 10

带回调的分页

1 / 9
回调日志:

无限滚动模拟

已加载:1 页 / 10 条
📄 数据项 #1
📄 数据项 #2
📄 数据项 #3
📄 数据项 #4
📄 数据项 #5
📄 数据项 #6
📄 数据项 #7
📄 数据项 #8
📄 数据项 #9
📄 数据项 #10
总数据: 100 条
已加载: 10 条
加载进度: 10%

API 参考

参数

参数类型默认值说明
optionsUsePaginationOptions{}配置选项

UsePaginationOptions

属性类型默认值说明
initialPagenumber1初始页码
initialPageSizenumber10初始每页大小
totalnumber | Ref<number>0总数据量
pageSizeOptionsnumber[][10, 20, 50, 100]可选的每页大小选项
onPageChange(page: number) => void-页码变化回调
onPageSizeChange(pageSize: number) => void-每页大小变化回调
onChange(page: number, pageSize: number) => void-分页信息变化回调

返回值

usePagination 返回一个包含分页信息和操作方法的数组:

typescript
const [paginationInfo, actions] = usePagination(options);
索引名称类型说明
0paginationInfoComputedRef<PaginationInfo>分页信息
1actionsPaginationActions分页操作方法

PaginationInfo

属性类型说明
currentnumber当前页码
pageSizenumber每页大小
totalnumber总数据量
totalPagesnumber总页数
hasPrevboolean是否有上一页
hasNextboolean是否有下一页
startIndexnumber当前页开始索引(从 0 开始)
endIndexnumber当前页结束索引(从 0 开始)

PaginationActions

方法类型说明
goToPage(page: number) => void跳转到指定页
prev() => void上一页
next() => void下一页
first() => void第一页
last() => void最后一页
setPageSize(pageSize: number) => void设置每页大小
setTotal(total: number) => void设置总数据量
reset() => void重置分页

类型定义

typescript
export interface UsePaginationOptions {
  initialPage?: number;
  initialPageSize?: number;
  total?: number | Ref<number>;
  pageSizeOptions?: number[];
  onPageChange?: (page: number) => void;
  onPageSizeChange?: (pageSize: number) => void;
  onChange?: (page: number, pageSize: number) => void;
}

export interface PaginationInfo {
  current: number;
  pageSize: number;
  total: number;
  totalPages: number;
  hasPrev: boolean;
  hasNext: boolean;
  startIndex: number;
  endIndex: number;
}

export interface PaginationActions {
  goToPage: (page: number) => void;
  prev: () => void;
  next: () => void;
  first: () => void;
  last: () => void;
  setPageSize: (pageSize: number) => void;
  setTotal: (total: number) => void;
  reset: () => void;
}

export type UsePaginationReturn = [ComputedRef<PaginationInfo>, PaginationActions];

export function usePagination(options?: UsePaginationOptions): UsePaginationReturn;

使用场景

  1. 数据表格 - 大量数据的分页显示
  2. 列表组件 - 长列表的分页浏览
  3. 搜索结果 - 搜索结果的分页展示
  4. 无限滚动 - 配合无限滚动实现数据加载
  5. API 分页 - 配合后端 API 实现服务端分页
  6. 前端分页 - 前端数据的客户端分页

高级用法

服务端分页

typescript
const total = ref(0);
const loading = ref(false);
const data = ref([]);

const [pagination, actions] = usePagination({
  initialPageSize: 20,
  total,
  onPageChange: async (page) => {
    await loadData(page, pagination.value.pageSize);
  },
  onPageSizeChange: async (pageSize) => {
    await loadData(1, pageSize);
  },
});

const loadData = async (page: number, pageSize: number) => {
  loading.value = true;
  try {
    const response = await api.getData({ page, pageSize });
    data.value = response.data;
    total.value = response.total;
  } finally {
    loading.value = false;
  }
};

前端分页

typescript
const allData = ref([
  /* 所有数据 */
]);
const [pagination, actions] = usePagination({
  initialPageSize: 10,
  total: computed(() => allData.value.length),
});

// 当前页数据
const currentPageData = computed(() => {
  const { startIndex, endIndex } = pagination.value;
  return allData.value.slice(startIndex, endIndex + 1);
});

搜索结果分页

typescript
const searchKeyword = ref("");
const filteredData = computed(() => {
  return allData.value.filter((item) => item.name.includes(searchKeyword.value));
});

const [pagination, actions] = usePagination({
  total: computed(() => filteredData.value.length),
});

// 搜索时重置到第一页
watch(searchKeyword, () => {
  actions.goToPage(1);
});

无限滚动

typescript
const loadedData = ref([]);
const [pagination, actions] = usePagination({
  initialPageSize: 20,
  total: 1000,
});

const loadMore = async () => {
  if (pagination.value.hasNext) {
    const newData = await fetchData(pagination.value.current + 1);
    loadedData.value.push(...newData);
    actions.next();
  }
};

// 滚动到底部时自动加载
const { arrivedState } = useScroll(scrollContainer);
watch(
  () => arrivedState.bottom,
  (isBottom) => {
    if (isBottom) {
      loadMore();
    }
  },
);

URL 同步

typescript
const route = useRoute();
const router = useRouter();

const [pagination, actions] = usePagination({
  initialPage: Number(route.query.page) || 1,
  initialPageSize: Number(route.query.pageSize) || 10,
  onChange: (page, pageSize) => {
    router.push({
      query: { ...route.query, page, pageSize },
    });
  },
});

注意事项

  1. 页码从 1 开始计算,索引从 0 开始计算
  2. 当总数据量变化时,会自动调整当前页码
  3. 设置每页大小时会智能计算新的页码位置
  4. 响应式 total 参数支持动态数据源
  5. 所有操作都会触发相应的回调函数
  6. 重置操作会恢复到初始状态
  7. 跳转页码会自动限制在有效范围内

基于 MIT 协议发布