How to paginate a table in Vue

Implementing pagination in data tables is essential for Vue applications that display large datasets efficiently without overwhelming the interface. As the creator of CoreUI with over 11 years of Vue development experience since 2014, I’ve built paginated tables in countless enterprise dashboards. The most effective solution is to track the current page in state and compute the visible rows based on page size. This approach provides smooth pagination with full control over navigation and display logic.

Use computed properties to paginate table data in Vue 3.

<template>
  <div>
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>Name</th>
          <th>Email</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for='item in paginatedData' :key='item.id'>
          <td>{{ item.id }}</td>
          <td>{{ item.name }}</td>
          <td>{{ item.email }}</td>
        </tr>
      </tbody>
    </table>

    <div class='pagination'>
      <button @click='prevPage' :disabled='currentPage === 1'>Previous</button>
      <span>Page {{ currentPage }} of {{ totalPages }}</span>
      <button @click='nextPage' :disabled='currentPage === totalPages'>Next</button>
    </div>
  </div>
</template>

<script>
import { ref, computed } from 'vue'

export default {
  setup() {
    const currentPage = ref(1)
    const itemsPerPage = 10

    const data = ref(Array.from({ length: 95 }, (_, i) => ({
      id: i + 1,
      name: `User ${i + 1}`,
      email: `user${i + 1}@example.com`
    })))

    const totalPages = computed(() =>
      Math.ceil(data.value.length / itemsPerPage)
    )

    const paginatedData = computed(() => {
      const start = (currentPage.value - 1) * itemsPerPage
      const end = start + itemsPerPage
      return data.value.slice(start, end)
    })

    const prevPage = () => {
      if (currentPage.value > 1) currentPage.value--
    }

    const nextPage = () => {
      if (currentPage.value < totalPages.value) currentPage.value++
    }

    return { currentPage, totalPages, paginatedData, prevPage, nextPage }
  }
}
</script>

The current page is tracked in a ref, starting at 1. A computed property calculates the total pages based on data length and items per page. Another computed property slices the data array to show only items for the current page. Navigation buttons update the page number with bounds checking to prevent invalid pages.

Best Practice Note

This is the same pagination pattern we use in CoreUI Vue tables for optimal performance. For large datasets, implement server-side pagination by fetching only the required page from your API. Add features like page size selection or jump-to-page input for enhanced navigation.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to limit items in a .map loop in JavaScript
How to limit items in a .map loop in JavaScript

How to Open All Links in New Tab Using JavaScript
How to Open All Links in New Tab Using JavaScript

How to Clone an Object in JavaScript
How to Clone an Object in JavaScript

How to Achieve Perfectly Rounded Corners in CSS
How to Achieve Perfectly Rounded Corners in CSS

Answers by CoreUI Core Team