Skip to content

Pagination

Pagination component

GitHub Repo stars GitHub forks

Repository status

CircleCI code coverage npm version license JavaScript Style Guide

Detailed changes for each release are documented in Changelog

If you are using vue 2.x version, please use v-page 2.x version instead

Installation

Install v-page component in to your project

sh
npm i v-page
sh
yarn add v-page
sh
pnpm add v-page

Globally install component

js
import { createApp } from 'vue'
import App from './app.vue'
import { PaginationBar } from 'v-page'

const app = createApp(App)
// globally install component
app.use(PaginationBar, {
  // globally config options
})
app.mount('#app')

Can global config options in plugin install

  • info
  • pageSizeMenu
  • language
  • align
  • border
  • pageNumber
  • first
  • last

You can also use components only where you need them, which is the more recommended way to use them. This is more conducive to code splitting and packaging

vue
<template>
  <PaginationBar />
</template>

<script setup>
import { PaginationBar } from 'v-page'
</script>

Use component on page

Typical usage of a pagination component

vue
<template>
  <div
    v-for="item in list"
    :key="item.key"
    v-text="item.name"
  />
  <PaginationBar
    v-model="pageNumber"
    :total-row="totalRow"
    @change="change"
  />
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { PaginationBar } from 'v-page'
import type { PageInfo } from 'v-page'

const pageNumber = ref<number>(3)
const totalRow = ref<number>(100)
const list = ref<unknown[]>([])
// respond for pagination change
function change (data: PageInfo): void {
  console.log(data) // { pageNumber: 1, pageSize: 10, totalPage: 10 }

  const params = {
    pageNumber: data.pageNumber,
    pageSize: data.pageSize,
    ...
  }
  // do some http request for example
  axios.post('some-api-address', params).then(resp => {
    // fetch new data and update data list and `totalRow` variable
    list.value = resp.list || []
    totalRow.value = resp.totalRow
  })
}
</script>

Examples

Quick demo

template
<PaginationBar
  :total-row="21"
  @change="change"
/>

Pagination change event response data

Event data logs
template
<div>
  <div
    v-for="item in listGallery"
    :key="item"
    v-text=item
  />
</div>
<PaginationBar
  :total-row="88"
  align="center"
  @change="changeGallery"
/>
js
import { ref } from 'vue'
import { PaginationBar } from 'v-page'

const srcList = Array(88).fill(0).map((val, index) => index + 1)
const listGallery = ref([])

function changeGallery ({ pageNumber, pageSize }) {
  const start = pageSize * (pageNumber - 1)
  const end = (start + pageSize) > srcList.length
    ? srcList.length
    : start + pageSize

  listGallery.value = srcList.filter((val, index) => {
    return index >= start && index < end
  })
}

Pagination operation

Some cases showing how pagination operation works

template
<div>
  <input type="text" v-model="inputPageNumber" />
  <button type="button" @click="goToInputPage" >go</button>
  <button
    type="button"
    @click="pageNumber++"
  >pageNumber + 1</button>
</div>

<PaginationBar v-model="pageNumber" />
js
import { ref } from 'vue'

const pageNumber = ref(3)
const inputPageNumber = ref('2')

function goToInputPage () {
  if (!inputPageNumber.value) return

  const newPageNumber = Number(inputPageNumber.value)

  if (window.isNaN(newPageNumber)) {
    inputPageNumber.value = ''
    return
  }
  pageNumber.value = newPageNumber
}

Number of records per page

pageSize specifies the number of records per page, and pageSizeMenu provides a list of the number of records per page for users to quickly select

template
<PaginationBar
  v-model:page-size="pageSize"
  :total-row="100"
/>
js
import { ref } from 'vue'

const pageSize = ref(25)

When the value list provided by pageSizeMenu does not have an item matching the pageSize value, the value will be automatically added to the pageSizeMenu list and selected

Alignment direction

template
<PaginationBar align="left" />
Specify alignment direction

Display border mode

template
<PaginationBar border />

Round style page number button

template
<PaginationBar circle />

Enabled and disabled

template
<PaginationBar :disabled="true" />

Modules on / off

Setup pagination modules on or off

Slot

v-page provides scoped slots to output pagination state for more easily customization

template
<PaginationBar
  border
  align="left"
  :total-row="28"
  :page-size-options="false"
  :info="false"
  :first="false"
  :last="false"
>
  <template #default="{
    pageNumber, pageSize, totalPage,
    totalRow, isFirst, isLast
  }">
    <div>
      <div>page: <span v-text="pageNumber" /></div>
      <div>pageSize: <span v-text="pageSize" /></div>
      <div>totalPage: <span v-text="totalPage" /></div>
      <div>totalRow: <span v-text="totalRow" /></div>
      <div>isFirst: <span v-text="isFirst" /></div>
      <div>isLast: <span v-text="isLast" /></div>
    </div>
  </template>
</PaginationBar>

Display all data option

Add All item to page size list to display all data without paging. When this item is selected, the response data of the change event is as follows

js
{
  pageNumber: 1,
  pageSize: 0,
  totalPage: 1
}

Props

v-page component props arguments

ts
interface PaginationProps {
  /**
   * The number of current page
   */
  modelValue?: number
  /**
   * The number of page size
   * @default 10
   */
  pageSize?: number
  /**
   * The number of total record
   */
  totalRow: number
  /**
   * Component language
   * @default `en`
   *
   * The complete language list
   * `cn` Simplified Chinese
   * `en` English
   * `de` German
   * `pt` Portuguese
   * `jp` Japanese
   */
  language?: 'cn' | 'en' | 'de' | 'jp' | 'pt'
  /**
   * List of the number of records per page, only
   * valid when `pageSizeOptions` is `true`
   * @default [10, 20, 50, 100]
   */
  pageSizeMenu?: number[]
  /**
   * Alignment direction
   * @default `right`
   */
  align?: 'left' | 'right' | 'center'
  /**
   * Disabled the pagination
   * @default false
   */
  disabled?: boolean
  /**
   * Display the border
   * @default true
   */
  border?: boolean
  /**
   * Round style page number button
   * @default false
   */
  circle?: boolean
  /**
   * Display page size list panel
   * @default true
   */
  pageSizeOptions?: boolean
  /**
   * Display page information panel
   * @default true
   */
  info?: boolean
  /**
   * Display page number buttons
   * @default true
   */
  pageNumber?: boolean
  /**
   * Display first page button
   * @default true
   */
  first?: boolean
  /**
   * Display last page button
   * @default true
   */
  last?: boolean
  /**
   * Whether add `All` item in page length list
   * @default false
   */
  displayAll?: boolean
  /**
   * Hide pagination when only have one page
   * @default false
   */
  hideOnSinglePage?: boolean
}

Events

Component operation response events

change

Response event triggered when data changes in the operation of pagination

ts
change: (data: PageInfo) => void
ts
interface PageInfo {
  // Current page number
  pageNumber: number
  // Page size
  pageSize: number
  // Total page
  totalPage: number
}
// You can directly use the type description provided by the component
import type { PageInfo } from 'v-page'

update:modelValue

The response event triggered when the current page changes

ts
`update:modelValue`: (value: number) => void

update:pageSize

The response event triggered when the number of records per page changes

ts
`update:pageSize`: (value: number) => void

Released under the MIT License.