In this tutorial, we are going to learn how to build a customizable and pageable data table in Vue application utilizing the Vuetify plugin. We will withal optically canvass how to integrate data sorting and filtering feature very facilely in Vue.js 2+.
What is Data Table?
A table is a relegation of data in rows and columns, or probably in a more perplexed structure. Tables are extensively utilized for data analysis, communication, and research and can be utilized in sundry domains such as print media, computer software, architectural elaboration, traffic signs, and many other places.
Data tables illustrate information in a more organizable manner in a grid-like composition that contains rows and columns. The architecture of a table is such that a utilizer can expeditiously scan the exhibited information.
A data table organizes information using column and rows, and a general DataTable has the following components:
- Columns
- Column header names
- Rows
- Footers
- Pagination
Getting Started
Create Vue project by using the following command.
vue create vue-data-table
Get inside the project directory.
cd vue-data-table
Start the app in the browser.
npm run serve
Install & Configure Vuetify Plugin
Creating a user-friendly application is a challenge in real-world. Vuetify is a powerful Vue UI Library with beautifully handcrafted Material Design UI Components. Vuetify offers 100% support for Vue, and comes with cleaner, semantic, and reusable UI components that lets you create a beautiful user interface in very less time..
You can use the following command to install Vuetify plugin in Vue.
npm install vuetify
Enable the Vuetify package globally in Vue by adding the following code in the main.js
.
// main.js
import Vue from 'vue'
import App from './App.vue'
import Vuetify from "vuetify";
import "vuetify/dist/vuetify.min.css";
Vue.use(Vuetify);
new Vue({
render: h => h(App)
}).$mount('#app')
Open public/index.html
file and add the Google fonts and Material Design Icons CSS in Vue app.
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@4.x/css/materialdesignicons.min.css" rel="stylesheet">
Vuetify Simple Table Example in Vue
The v-simple-table directive creates the table component in Vue; it needs to be placed inside your Vue component and should wrap the table tag.
<template>
<v-simple-table>
<template v-slot:default>
<thead>
<tr>
<th class="text-left">Name</th>
<th class="text-left">Calories</th>
</tr>
</thead>
<tbody>
<tr v-for="food in FOOD" :key="food.name">
<td>{{ food.name }}</td>
<td>{{ food.calories }}</td>
</tr>
</tbody>
</template>
</v-simple-table>
</template>
<script>
export default {
data () {
return {
FOOD: [
{
name: 'Burger',
calories: 660,
},
{
name: 'Sandwich',
calories: 660,
},
{
name: 'Cheese Whopper',
calories: 790,
},
{
name: 'Bacon King',
calories: 1150,
},
{
name: 'Farmhouse',
calories: 1220,
},
{
name: 'Grilled Chicken',
calories: 470,
},
{
name: 'Snickers Pie',
calories: 300,
},
{
name: 'Veggie Burger',
calories: 390,
},
{
name: 'Donut',
calories: 500,
},
{
name: 'Grilled Hot Dog',
calories: 310,
},
{
name: 'French Fry',
calories: 380,
},
],
}
},
}
</script>
FOOD is an array that contains some dummy food data in JSON format. The v-for
directive is iterating FOOD array and displaying the data with the table component.
Fixed Header Table Example
We should add the fixed-header property along with height property in v-simple-table
directive to make the table header fixed.
<template>
<v-simple-table fixed-header height="400px">
<template v-slot:default>
<thead>
<tr>
<th class="text-left">Name</th>
<th class="text-left">Calories</th>
</tr>
</thead>
<tbody>
<tr v-for="food in FOOD" :key="food.name">
<td>{{ food.name }}</td>
<td>{{ food.calories }}</td>
</tr>
</tbody>
</template>
</v-simple-table>
</template>
<script>
export default {
data () {
return {
FOOD: [
{
name: 'Burger',
calories: 660,
},
{
name: 'Sandwich',
calories: 660,
},
{
name: 'Cheese Whopper',
calories: 790,
},
{
name: 'Bacon King',
calories: 1150,
},
{
name: 'Farmhouse',
calories: 1220,
},
{
name: 'Grilled Chicken',
calories: 470,
},
{
name: 'Snickers Pie',
calories: 300,
},
{
name: 'Veggie Burger',
calories: 390,
},
{
name: 'Donut',
calories: 500,
},
{
name: 'Grilled Hot Dog',
calories: 310,
},
{
name: 'French Fry',
calories: 380,
},
],
}
},
}
</script>
Table Dark theme
To update the table current theme to dark theme can be done by just adding dark
tag to v-simple-table component.
<template>
<v-simple-table dark>
<template v-slot:default>
<thead>
<tr>
<th class="text-left">Name</th>
<th class="text-left">Calories</th>
</tr>
</thead>
<tbody>
<tr v-for="food in FOOD" :key="food.name">
<td>{{ food.name }}</td>
<td>{{ food.calories }}</td>
</tr>
</tbody>
</template>
</v-simple-table>
</template>
<script>
export default {
data () {
return {
FOOD: [...],
}
},
}
</script>
Here is how the table looks in Vue when updated to dark theme.
Build Data Table in Vue.js
Next, we are going to create Data Table in Vue using Vuetify plugin. The v-data-table
component is recommended for showing data in the table form. It comes with some of the core features of DataTable, such as sorting, searching, pagination, inline-editing, and row selection.
<template>
<v-data-table dark
:headers="headers"
:items="food"
:items-per-page="7"
class="elevation-1"
></v-data-table>
</template>
<script>
export default {
data () {
return {
headers: [
{
text: 'Food Items (Nutrition 100g)',
align: 'start',
sortable: false,
value: 'name',
},
{ text: 'Energy', value: 'energy' },
{ text: 'Protein', value: 'protein' },
{ text: 'Fat', value: 'fat' },
{ text: 'Carbohydrate', value: 'carbohydrate' },
{ text: 'Sodium', value: 'sodium' },
],
food: [
{
name: 'Muesli (Almond)',
energy: 201,
protein: 5.0,
fat: 34,
carbohydrate: 5.5,
sodium: '1.5%'
},
{
name: 'Wholegrain Rolled Oats',
energy: 301,
protein: 3.0,
fat: 54,
carbohydrate: 3.5,
sodium: '2.5%'
},
{
name: 'Almond Milk',
energy: 130,
protein: 6.0,
fat: 24,
carbohydrate: 3.9,
sodium: '3.5%'
},
{
name: 'Firm Tofu',
energy: 101,
protein: 2.0,
fat: 25,
carbohydrate: 2.1,
sodium: '0.5%'
},
{
name: 'Hummus',
energy: 709,
protein: 8.4,
fat: 10.8,
carbohydrate: 4.6,
sodium: '2.5%'
},
{
name: 'Peanut Butter',
energy: 2580,
protein: 28,
fat: 50,
carbohydrate: 12,
sodium: '3.5%'
},
{
name: 'Tahini',
energy: 2760,
protein: 25.0,
fat: 57.3,
carbohydrate: 12,
sodium: '7.0%'
},
{
name: 'Butter Beans',
energy: 384,
protein: 7.4,
fat: 0.9,
carbohydrate: 15.2,
sodium: '3.1%'
},
{
name: 'Chickpeas',
energy: 391,
protein: 5.0,
fat: 34,
carbohydrate: 5.5,
sodium: '2.3%'
},
{
name: 'Lentils',
energy: 290,
protein: 4.2,
fat: 0.9,
carbohydrate: 15,
sodium: '1.0%'
}
],
}
},
}
</script>
TypeError: Cannot read property ‘width’ of undefined
To get rid from the width undefined Vuetify error, we must define vuetify library to mounting function in main.js
file as mentioned below.
import Vue from 'vue'
import App from './App.vue'
import Vuetify from 'vuetify'
import "vuetify/dist/vuetify.min.css";
Vue.use(Vuetify)
new Vue({
vuetify: new Vuetify(),
render: h => h(App)
}).$mount('#app')
Search DataTable in Vue
Add a search prop to enable filtering feature in Data Tables is very easy in Vue with Vuetify.js.
<template>
<v-card>
<v-card-title>
Food Data
<v-spacer></v-spacer>
<v-text-field
v-model="search"
append-icon="mdi-magnify"
label="Search"
single-line
hide-details
></v-text-field>
</v-card-title>
<v-data-table
:headers="headers"
:items="food"
:search="search"
></v-data-table>
</v-card>
</template>
<script>
export default {
data () {
return {
search: '',
headers: [
{
text: 'Food Items (Nutrition 100g)',
align: 'start',
sortable: false,
value: 'name',
},
{ text: 'Energy', value: 'energy' },
{ text: 'Protein', value: 'protein' },
{ text: 'Fat', value: 'fat' },
{ text: 'Carbohydrate', value: 'carbohydrate' },
{ text: 'Sodium', value: 'sodium' },
],
food: [
{
name: 'Muesli (Almond)',
energy: 201,
protein: 5.0,
fat: 34,
carbohydrate: 5.5,
sodium: '1.5%'
},
{
name: 'Wholegrain Rolled Oats',
energy: 301,
protein: 3.0,
fat: 54,
carbohydrate: 3.5,
sodium: '2.5%'
},
{
name: 'Almond Milk',
energy: 130,
protein: 6.0,
fat: 24,
carbohydrate: 3.9,
sodium: '3.5%'
},
{
name: 'Firm Tofu',
energy: 101,
protein: 2.0,
fat: 25,
carbohydrate: 2.1,
sodium: '0.5%'
},
{
name: 'Hummus',
energy: 709,
protein: 8.4,
fat: 10.8,
carbohydrate: 4.6,
sodium: '2.5%'
},
{
name: 'Peanut Butter',
energy: 2580,
protein: 28,
fat: 50,
carbohydrate: 12,
sodium: '3.5%'
},
{
name: 'Tahini',
energy: 2760,
protein: 25.0,
fat: 57.3,
carbohydrate: 12,
sodium: '7.0%'
},
{
name: 'Butter Beans',
energy: 384,
protein: 7.4,
fat: 0.9,
carbohydrate: 15.2,
sodium: '3.1%'
},
{
name: 'Chickpeas',
energy: 391,
protein: 5.0,
fat: 34,
carbohydrate: 5.5,
sodium: '2.3%'
},
{
name: 'Lentils',
energy: 290,
protein: 4.2,
fat: 0.9,
carbohydrate: 15,
sodium: '1.0%'
}
],
}
},
}
</script>
i hope you like this article.