Components/Pagination

Pagination

Page navigation for long lists

VerifiedSince 0.3.4
<script>
import { ref } from 'vue'
const page = ref(1)
</script>

Usage

Pagination

Navigate through pages of data. page-sizes puts the items-per-page selector inside the pagination, and TxPagination recalculates the page count for the new size; this demo returns to page 1 when the size changes, as the next section explains.

Loading demo...

Page size

page-sizes adds a size selector after the page buttons, named by its visible page-size-label, and lays the controls out in one wrapping row. Picking a size emits update:pageSize and pageSizeChange and leaves the page alone, so the host decides where the reader lands; this demo goes back to page 1.

Loading demo...

Best Practices

  • Prefer total + pageSize so the UI can reflect item counts; use totalPages only when the backend cannot return totals.
  • Keep currentPage one-based. Initialize the model to 1, not 0.
  • Reset currentPage to 1 when filters or search terms change and the old page may be out of range.
  • Reset it on pageSizeChange too: the component only reports the new size, and the rows the reader was looking at have moved. A page past the new count is clamped either way.
  • Prefer pageSizes over a size select of your own beside the pagination: it is named by its visible label and sits in the pagination's own row.
  • Keep pagination adjacent to the list or table it controls.
  • Use the info slot for localized range copy such as “Viewing 21–40 of 120 items”.

API Reference

Props

PropertyTypeDefaultDescription
currentPageCurrent page
pageSizeItems per page; pair with v-model:page-size when the reader can change it
pageSizesPage-size choices. Supplying them renders a size selector after the page buttons and lays the controls out in one wrapping row; without them the DOM is unchanged. Invalid sizes are dropped, and a pageSize missing from the list joins it
pageSizeLabelVisible label in front of the size selector; it also names the selector for assistive technology
total-Total item count; when omitted or 0, page count falls back to totalPages
totalPages-Explicit total page count; used when total is not provided
prevIconCustom previous icon class consumed by TxIcon; empty uses the bundled SVG chevron
nextIconCustom next icon class consumed by TxIcon; empty uses the bundled SVG chevron
showInfoShow total info
showFirstLastShow first/last buttons

Events

PropertyTypeDefaultDescription
update:currentPage-v-model current page update
pageChange-Triggered when users navigate to another page
update:pageSize-v-model page size update when the reader picks another size; the current page is left as it is
pageSizeChange-Triggered when the reader picks another page size

Slots

PropertyTypeDefaultDescription
info-Custom page info area

Dashboard Data Operations

Place pagination directly below the table and bind it to the same reactive model as filtering and selection; avoid floating pagination away from the list container.

Data operations panel

Pagination shares the data-region state with DataTable and Skeleton.

Loading demo...

Overview

  • total takes precedence for page-count calculation with pageSize; totalPages is used when total is not provided.
  • showFirstLast renders first/last page jump buttons, and boundary pages disable first/previous or next/last controls.
  • The active page button exposes aria-current="page"; previous/next/first/last controls expose readable aria-label values.
  • Default navigation chevrons are bundled SVGs and do not require host icon generation; custom icon classes still use TxIcon.
  • With pageSizes, a div.tx-pagination__size sits between the page list and the info: a visible span.tx-pagination__size-label and an 88px TxSelect whose combobox carries aria-labelledby pointing at that label. The nav gains has-page-size and lays the list, the selector and the info out in one centred row that wraps when narrow. Without pageSizes (or with only invalid sizes) none of this renders.
  • Picking a size emits update:pageSize and then pageSizeChange, and only when the size differs from pageSize. currentPage is left to the host; if the larger size leaves fewer pages than the current one, the existing clamp emits update:currentPage with the last page.
  • The page-size selector passes aria-labelledby directly to TxSelect, which forwards it to the combobox from the first render; no DOM-writing ref callback is needed. The on-demand style plugin loads the select's sheets with pagination; manual style imports still need select/style.css and its dependencies.

Technologies

  • Source: packages/tuffex/packages/components/src/pagination/src/TxPagination.vue confirms total/page-size page calculation, ellipsis window generation, boundary guards, first/last controls, info slot props, aria-current, and readable pagination button labels.
  • Type contracts: packages/tuffex/packages/components/src/pagination/src/types.ts defines PaginationProps and PaginationEmits.
  • Verified coverage: packages/tuffex/packages/components/src/pagination/__tests__/pagination.test.ts covers total-derived pages, ellipsis rendering, active page semantics, blocked out-of-range navigation, first/last controls, boundary disabled states, localized control labels, and custom info slot props. pagination-page-size.test.ts (6 cases) covers the unchanged DOM without valid pageSizes, the selector's order and its aria-labelledby name, the size events without a page change, no event for the current size, a missing pageSize joining the options, and a v-model:page-size round trip where the clamp pulls the page back.
  • Recommendation: prefer total + pageSize; use totalPages only when the backend returns a page count without total items.
查看源码
packages/tuffex/packages/components/src/pagination/index.ts