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.
Table Of Contents
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
.
Features
- Pagination
- Sorting
- 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
.