Skip to content

usePagination

usePagination 是一个用于处理分页逻辑的 Vue 3 Composition API Hook,完全对齐 Element Plus pagination 组件的 API 设计。

特性

  • 🎯 完全对齐 Element Plus - 字段名和行为与 Element Plus pagination 组件保持一致
  • 🔄 向后兼容 - 支持旧版本 API,并提供迁移警告
  • 📦 类型安全 - 完整的 TypeScript 类型定义
  • 🛠️ 易于使用 - 简单的 API 设计,开箱即用

基本用法

新版本 API (推荐)

vue
<template>
  <div>
    <!-- 直接绑定到 Element Plus pagination 组件 -->
    <el-pagination
      v-model:current-page="pagination.currentPage"
      v-model:page-size="pagination.pageSize"
      :page-sizes="pagination.pageSizes"
      :layout="pagination.layout"
      :total="pagination.total"
      @size-change="handlers.onSizeChange"
      @current-change="handlers.onCurrentChange"
    />
  </div>
</template>

<script setup lang="ts">
import { usePagination } from '@qxs-bns/hooks'

const { pagination, getParams, handlePagination } = usePagination({
  currentPage: 1,
  pageSize: 20,
  total: 1000,
  pageSizes: [10, 20, 50, 100],
  layout: 'total, sizes, prev, pager, next, jumper',
})

// 处理分页变化
const handlers = handlePagination(() => {
  const params = getParams()
  console.log('分页参数:', params)
  // 调用 API 获取数据
  fetchData(params)
})

async function fetchData(params) {
  // API 调用逻辑
}
</script>

API 参考

PaginationParams

参数说明类型默认值
currentPage当前页数number1
pageSize每页显示条目个数number10
total总条目数number0
pageSizes每页显示个数选择器的选项设置number[][10, 20, 50, 100]
layout组件布局string'total, sizes, prev, pager, next'
sort排序信息object | nullnull
order排序方向string | nullnull

废弃参数 (兼容性)

参数说明替代参数状态
page当前页数currentPage⚠️ 已废弃
sizes每页显示个数选择器选项pageSizes⚠️ 已废弃

返回值

名称说明类型
pagination分页响应式对象Ref<PaginationParams>
getParams获取用于 API 调用的参数() => Pagination
handlePagination获取分页事件处理器(getData: () => void) => PaginationHandlers
getLegacyParams获取旧版本格式参数() => LegacyPaginationParams ⚠️ 已废弃

PaginationHandlers

名称说明类型
onSizeChange页面大小改变处理器(size: number) => void
onCurrentChange当前页改变处理器(page: number) => void
onSortChange排序改变处理器(prop: any, order: string) => void

迁移指南

从旧版本迁移

如果你正在使用旧版本的 API,请按照以下步骤迁移:

1. 更新参数名

typescript
// 旧版本 ❌
const { pagination } = usePagination({
  page: 1,           // 改为 currentPage
  size: 20,          // 改为 pageSize  
  sizes: [10, 20],   // 改为 pageSizes
})

// 新版本 ✅
const { pagination } = usePagination({
  currentPage: 1,
  pageSize: 20,
  pageSizes: [10, 20],
})

2. 更新模板绑定

vue
<!-- 旧版本 ❌ -->
<el-pagination
  v-model:current-page="pagination.page"
  v-model:page-size="pagination.size"
  :page-sizes="pagination.sizes"
/>

<!-- 新版本 ✅ -->
<el-pagination
  v-model:current-page="pagination.currentPage"
  v-model:page-size="pagination.pageSize"
  :page-sizes="pagination.pageSizes"
/>

3. 兼容性支持

在迁移期间,你可以继续使用旧版本 API,系统会显示警告提示:

typescript
// 会显示警告,但仍然可以工作
const { pagination } = usePagination({
  page: 1,        // ⚠️ 警告: 参数 "page" 已废弃,请使用 "currentPage"
  sizes: [10, 20] // ⚠️ 警告: 参数 "sizes" 已废弃,请使用 "pageSizes"
})

高级用法

自定义分页配置

typescript
const { pagination, getParams, handlePagination } = usePagination({
  currentPage: 1,
  pageSize: 50,
  total: 0,
  pageSizes: [20, 50, 100, 200],
  layout: 'total, prev, pager, next, jumper',
})

带排序的分页

vue
<template>
  <div>
    <el-table
      :data="tableData"
      @sort-change="handlers.onSortChange"
    >
      <el-table-column prop="name" label="名称" sortable="custom" />
      <el-table-column prop="date" label="日期" sortable="custom" />
    </el-table>
    
    <el-pagination
      v-model:current-page="pagination.currentPage"
      v-model:page-size="pagination.pageSize"
      :page-sizes="pagination.pageSizes"
      :layout="pagination.layout"
      :total="pagination.total"
      @size-change="handlers.onSizeChange"
      @current-change="handlers.onCurrentChange"
    />
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { usePagination } from '@qxs-bns/hooks'

const tableData = ref([])

const { pagination, getParams, handlePagination } = usePagination({
  currentPage: 1,
  pageSize: 20,
  total: 0,
  pageSizes: [10, 20, 50, 100],
  layout: 'total, sizes, prev, pager, next',
})

const handlers = handlePagination(loadData)

async function loadData() {
  const params = getParams()
  console.log('请求参数:', params)
  
  // 调用 API
  const response = await fetchTableData(params)
  tableData.value = response.data
  pagination.value.total = response.total
}

// 初始加载
loadData()
</script>

最佳实践

  1. 使用新版本 API:推荐使用 currentPagepageSizepageSizes 等新字段名
  2. 合理设置 layout:根据实际需求选择合适的分页布局
  3. 响应式更新 total:在数据加载完成后及时更新 pagination.total
  4. 错误处理:在数据加载失败时提供用户友好的错误提示

Released under the MIT License.