In this post I will show you how to display data in tabular view based using a very powerful datatable component in Vuejs 2.
Admin panels or dashboards often have many pages that displays a listing of data for example in a news website may be you have a listing page of categories and listing page of posts and those listing displayed in a table, so to accomplish such task in Vuejs we will use a ready made component called vuetable-2 you can find it in this github link.
Installation
First method: Install globally
npm i -S vuetable-2
Second method: Install per project
npm install vuetable-2
Using
import Vue from 'vue' import Vuetable from 'vuetable-2'
Then in your main component you can display it like that:
<vuetable ref="vuetable"></vuetable>
Let’s see a full working example imagine we have this component and we want to display data from remote api so create this component:
List.vue
<template> <div> <vuetable ref="vuetable" :api-url="api_url" :fields="fields" ></vuetable> </div> </template> <script> import Vue from 'vue' import Vuetable from 'vuetable-2' export default { data() { return { api_url: "https://vuetable.ratiw.net/api/users", fields: ['name', 'email', 'birthdate'] } }, components: { Vuetable } } </script>
In the code above we loaded Vuetable and then added <vuetable> tag our component template and passed it two properties “api-url” and “fields” the first one represents api end point that you will fetch the data from in our case i used a sample url to illustrate the example and the second one represents the fields that you want to display.
Then run
npm run dev
Great Now you see the datatable along with the data, so let’s see the structure of the api end point.
End Point Response Structure:
Vuetable component requires specific endpoint response structure in order to work properly as with other datatable libraries the endpoint must support a lot of things like:
- Pagination
- Filtering
- Sorting
- From and To
- The actual data
So if we investigate the previous api url that we used above we notice it has the following structure:
{ "total": 200, // total number of results "per_page": 15, // number of items per page "current_page": 1, // current page number "last_page": 14, // last page number "next_page_url": "https://vuetable.ratiw.net/api/users?page=2", // next page url along with pagination param or null if this is the first page "prev_page_url": null, // prev page url along with pagination param or null if this the last page "from": 1, // id of first item "to": 15, // id of last item "data": [ // the actual data { "id": 1, "name": "Noelia O'Kon", "nickname": "asperiores", "email": "otho.smitham@example.com", "birthdate": "1978-06-28 00:00:00", }, { }, { }, ...... ...... ] }
So you must create your api to conform to this structure and below is a description of each item:
- total: represents the total number of results.
- per_page: number of items per page for example 10 (used for pagination).
- current_page: represents the current page number (used for pagination).
- last_page: represents the last page number (used for pagination).
- next_page_url: represents next page url along with with page param or null (used for pagination).
- prev_page_url: represents prev page url along with page param or null (used for pagination).
- from: id of first item
- to: id of last item
- data: array of data objects.
For the parameters that you pass to the api url to filter or paginate, your api must accept these parameters:
http://endpoint url/?page=&per_page=&sort=&filter=
- page: page number
- per_page: number of items per page
- sort: <field>|<direction> so to sort by title desc you send: sort=title|desc
- filter: this is the filter text.
Change field titles:
In the previous we noticed the displayed titles in the field names coming from the api, but in some cases we want to display custom field titles so to to do this we add a second item for each object in the fields array like this:
export default { components: { Vuetable }, data () { return { fields: [ { name: 'name', title: 'Name' -----> field title }, { name: 'email', title: 'Email' }, { name: 'birthdate', title: 'Date of birth' } ] } } }
The fields
prop will internally get converted by Vuetable to an array of field definition object.
Format fields:
Sometimes you don’t want to display field as is for example may be your response have a date field and your want to format that date or the object contain image field and you want to display that image in <img> tag, to do this we use a callback function that take the field value and return the formatted one like this:
data () { return { fields: [ //... { name: 'email', title: 'Email', callback: 'formatEmail' }, //... ] } }, methods: { formatEmail (value) { return '<a href="email:'+value+'">'+value+'</a>'; } }
Adding Pagination:
To add pagination Vuetable make use of two other components, VuetablePagination and VuetablePaginationInfo, Now, let’s put the pagination components in our List.vue template.
<template> <div> <vuetable ref="vuetable" :api-url="api_url" :fields="fields" pagination-path="" @vuetable:pagination-data="onPaginationData" ></vuetable> <vuetable-pagination-info ref="paginationInfo" ------> pagination info ></vuetable-pagination-info> <vuetable-pagination ref="pagination" @vuetable-pagination:change-page="onChangePage"> </vuetable-pagination> </div> </template> <script> import Vue from 'vue' import Vuetable from 'vuetable-2' import VuetablePagination from 'vuetable-2/src/components/VuetablePagination' import VuetablePaginationInfo from 'vuetable-2/src/components/VuetablePaginationInfo' export default { data() { return { api_url: "https://vuetable.ratiw.net/api/users", fields: [ { name: 'name', title: 'Name' -----> field title }, { name: 'email', title: 'Email' }, { name: 'birthdate', title: 'Date of birth' } ] } }, components: { Vuetable, VuetablePagination, VuetablePaginationInfo }, methods: { onPaginationData (paginationData) { this.$refs.pagination.setPaginationData(paginationData) this.$refs.paginationInfo.setPaginationData(paginationData) }, onChangePage (page) { this.$refs.vuetable.changePage(page) } } } </script>
There are a lot of work in the above code but let’s break things, the pagination has two components the first one that display the pagination links and also listen for events like clicking on page number, the second component display pagination info like this:
Displaying 1 to 15 of 200 items
So in order to use them we must import and include the components in our template as shown above:
<vuetable-pagination-info ref="paginationInfo"></vuetable-pagination-info> ----> pagination info <vuetable-pagination ref="pagination" @vuetable-pagination:change-page="onChangePage"> </vuetable-pagination> -----> pagination links
Note that the pagination uses the response data returned from the json object as described above and uses them to bind and render the page links.
Now, we are ready to bind VuetablePagination to Vuetable so that it receives pagination information that it can use. We do this in 3 steps:
- listen to
vuetable:pagination-data
event on Vuetable and specify the binding handler function. - listen to
vuetable-pagination:change-page
event on VuetablePagination and specify the binding handler function. - define both of the binding handler functions in our component.
<vuetable ref="vuetable" api-url="https://vuetable.ratiw.net/api/users" :fields="fields" pagination-path="" @vuetable:pagination-data="onPaginationData"
<vuetable-pagination ref="pagination" @vuetable-pagination:change-page="onChangePage" ></vuetable-pagination>
methods: { //... onPaginationData (paginationData) { this.$refs.pagination.setPaginationData(paginationData) }, onChangePage (page) { this.$refs.vuetable.changePage(page) } }
Adding Sorting:
To make fields sortable we add another item in every object of the field array called sortField you tell Vuetable that that particular field is sortable. Vuetable will render the column header for that field to be clickable for sorting and the ascending or descending sort icon will appear after the column name in the table header.
data() { return { api_url: "https://vuetable.ratiw.net/api/users", fields: [ { name: 'name', title: 'Name', sortField: 'name' }, { name: 'email', title: 'Email', sortField: 'email' }, { name: 'birthdate', title: 'Date of birth', sortField: 'birthdate' } ] } },
Again your api must support sorting in order for the sorting to work properly as described in the request parameters above when you click on any field to sort a request made to the api url with the sort parameter for example if you click on title field this request sent:
https://vuetable.ratiw.net/api/users?sort=title|desc
Default Sort Order
Also you can use sort-order
prop to specify the initial sort order for specific field(s). For example, you would like the data to be initially sorted by email
field, you can do so by:
<template> <vuetable ref="vuetable" :sort-order="sortOrder" ></vuetable> </template> <script> //... data () { return { sortOrder: [ { field: 'email', sortField: 'email', direction: 'asc' } ] } } </script>
Up till now we have displayed the datatable, adding pagination and pagination info, and enabled sorting, there are still a lot of the other features available in this component, in this link you can find more customization options that suite your needs.