ホーム > Laravel > How to Create Beautiful Tables with Vuetify【v-data-table】
Laravel

How to Create Beautiful Tables with Vuetify【v-data-table】

Thank you for your continued support.
This article contains advertisements that help fund our operations.

This article summarizes how to create beautiful tables using Vuetify.

What is v-data-table?

Vuetify provides a component that allows you to easily create beautiful and highly functional tables.

That component is v-data-table.

Data tables - Vuetify

Features

  1. Pagination
  2. Sorting
  3. Filtering

These features can be easily implemented.

If you try to build them yourself, it can be quite challenging.

Basic Usage

<script setup>
  import { Head, Link } from "@inertiajs/vue3"

  const headers = [
    {
      title: "Title",
      value: "title",
    },
    { title: "Category", value: "category" },
    { title: "Content", value: "content" },
  ]
  const items = [
    {
      title: "Title 1",
      category: "Category 1",
      content: "Content content content content content 1",
    },
    {
      title: "Title 2",
      category: "Category 2",
      content: "Content content content content content 2",
    },
    {
      title: "Title 1",
      category: "Category 1",
      content: "Content content content content content 2",
    },
  ]
</script>

<template>
  <div>
    <head title="Welcome" />
    <v-data-table
      :headers="headers"
      :items="items"
      item-key="name"
      items-per-page="5"
    ></v-data-table>
  </div>
</template>

Defining Table Headers with headers

The title represents the displayed text, while the value corresponds to the property.

const headers = [
  {
    title: "Title",
    value: "title",
  },
  { title: "Category", value: "category" },
  { title: "Content", value: "content" },
]

Displaying Data with items

The properties specified in headers.value will be displayed in each column.

const items = [
  {
    title: "Title 1",
    category: "Category 1",
    content: "Content content content content content 1",
  },
  {
    title: "Title 2",
    category: "Category 2",
    content: "Content content content content content 2",
  },
  {
    title: "Title 1",
    category: "Category 1",
    content: "Content content content content content 2",
  },
]

Passing Props to the Component

The headers and items defined earlier are passed as props.

<v-data-table
  :headers="headers"
  :items="items"
  item-key="name"
  items-per-page="5"
></v-data-table>

This is the basic structure.

Using Data from an API

If you store data in a variable and pass it as a prop, it will be displayed in the table.

<script setup>
  import { Head } from "@inertiajs/vue3"
  import { ref, onMounted } from "vue"
  import axios from "axios"

  const posts = ref([])

  const headers = [
    { title: "Title", value: "title" },
    { title: "Category", value: "category" },
    { title: "Content", value: "content" },
  ]

  const fetchPosts = async () => {
    try {
      const response = await axios.get("/api/posts") // Modify API endpoint as needed
      posts.value = response.data
    } catch (error) {
      console.error("Error fetching posts:", error)
    }
  }

  onMounted(fetchPosts)
</script>

<template>
  <div>
    <head title="Welcome" />
    <v-data-table
      :headers="headers"
      :items="posts"
      item-key="id"
      items-per-page="5"
    ></v-data-table>
  </div>
</template>

Changing the Number of Items per Page

Use items-per-page to specify the number of items displayed per page.

<v-data-table
  :headers="headers"
  :items="posts"
  item-key="name"
  items-per-page="100"
></v-data-table>

Adding Sorting

Adding sortable to headers enables sorting with ascending and descending order arrows.

const headers = [
  {
    title: "Title",
    value: "title",
  },
  { title: "Category", value: "category", sortable: true },
  { title: "Content", value: "content" },
]

If you want to set a default sorting order, use sort-by.

const sortBy = [{ key: 'category', order: 'desc' }]

<v-data-table
  :headers="headers"
  :items="posts"
  item-key="name"
  items-per-page="5"
  :sort-by="sortBy"
></v-data-table>

Filtering by Text

Pass a search term as the search prop.

Create an input field with v-model, and pass the variable to search.

<script setup>
  import { ref } from "vue"

  const searchWord = ref("") // Add this
</script>

<v-text-field v-model="searchWord" label="Filter"></v-text-field> // Add this
<v-data-table
  :headers="headers"
  :items="posts"
  item-key="name"
  items-per-page="5"
  :search="searchWord"
></v-data-table>

Handling Large Data Sets

If loading all data at once is too heavy, consider using a "Virtual Table" or a "Server-Side Table."

Virtual Table

This method renders only a portion of rows, reducing the performance impact.

However, pagination cannot be used.

Simply change the component to v-data-table-virtual.

<template>
  <div>
    <v-text-field v-model="searchWord" label="Filter"></v-text-field>
    <v-data-table-virtual
      :headers="headers"
      :items="posts"
      item-key="name"
      :search="searchWord"
    ></v-data-table-virtual>
  </div>
</template>

Server-Side Table

This method fetches data dynamically based on user actions, such as sorting or pagination.

Use v-data-table-server and fetch new data when events occur.

<script setup>
  import { ref } from "vue"

  const headers = [
    { title: "Title", value: "title" },
    { title: "Category", value: "category", sortable: true },
    { title: "Content", value: "content" },
  ]

  const loadItems = ({ page, itemsPerPage, sortBy }) => {
    console.log(page)
    console.log(itemsPerPage)
    console.log(sortBy)
  }
</script>

<template>
  <div>
    <v-data-table-server
      :items="posts"
      :headers="headers"
      @update:options="loadItems"
    ></v-data-table-server>
  </div>
</template>

When table actions occur, the server fetches updated data accordingly.

const posts = ref([])

const loadItems = async ({ page, itemsPerPage }) => {
  const { data } = await axios.get("https://localhost/api/posts", {
    params: {
      page: page,
      per_page: itemsPerPage,
    },
  })
  posts.value = data
}

This concludes the explanation of v-data-table.

Please Provide Feedback
We would appreciate your feedback on this article. Feel free to leave a comment on any relevant YouTube video or reach out through the contact form. Thank you!