Vue DataView displays data in grid or list layout with pagination and sorting features. It supports Vue 3 with PrimeVue 3 and Vue 2 with PrimeVue 2.
Setup
Refer to PrimeVue setup documentation for download and installation steps for your environment such as Vue CLI, Vite or browser.
Import
import DataView from 'primevue/dataview';
PrimeFlex
DataView utilizes PrimeFlex library so it needs to be installed before getting started. Refer to FlexGrid documentation for details.
Getting Started
DataView requires a collection of items as its value and one or more templates depending on the layout mode e.g. list and grid. Throughout the samples, a car interface having vin, brand, year and color properties are used to define an object to be displayed by the dataview. Cars are loaded by a CarService that connects to a server to fetch the cars.
export default {
data() {
return {
cars: null,
}
},
carService: null,
created() {
this.carService = new CarService();
},
mounted() {
this.carService.getCarsLarge().then(data => this.cars = data);
}
}
Layouts
DataView has two layout modes; list and grid where a separate template is used to render an item in each mode. In list mode name of the template is "list" whereas in grid mode it is "grid".
Note that there is no restriction to use both layouts at the same time, you may configure only one layout using the layout property with the corresponding template.
<template #list="slotProps">
<div class="p-col-12">
<div class="car-details">
<div>
<img :src="'demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand"/>
<div class="p-grid">
<div class="p-col-12">Vin: <b>{{slotProps.data.vin}}</b></div>
<div class="p-col-12">Year: <b>{{slotProps.data.year}}</b></div>
<div class="p-col-12">Brand: <b>{{slotProps.data.brand}}</b></div>
<div class="p-col-12">Color: <b>{{slotProps.data.color}}</b></div>
</div>
</div>
<Button icon="pi pi-search"></Button>
</div>
</div>
</template>
<template #grid="slotProps">
<div style="padding: .5em" class="p-col-12 p-md-3">
<Panel :header="slotProps.data.vin" style="text-align: center">
<img :src="'demo/images/car/' + slotProps.data.brand + '.png'" :alt="slotProps.data.brand"/>
<div class="car-detail">{{slotProps.data.year}} - {{slotProps.data.color}}</div>
<Button icon="pi pi-search"></Button>
</Panel>
</div>
</template>
Sections
Header and Footer are the two templates that are capable of displaying custom content.
<template #header>Header Content</template>
<template #footer>Footer Content</template>
Empty Message
Where there is no data to display, the optional empty template can be used to display information.
<template #empty>No records found.</template>
DataViewLayoutOptions
When both layout modes are enabled in DataView, a UI element would be necessary to let the user toggle between the view. DataViewLayoutOptions is a helper component to display a buttonset to choose the layout mode in DataView. Location of the DataViewLayoutOptions should be inside the DataView component. If you prefer a different UI element you can create your own that updates the layout property of the DataView.
<DataView :value="cars" :layout="layout">
<template #header>
<DataViewLayoutOptions v-model="layout"></DataViewLayoutOptions>
</template>
<template #list="slotProps" >
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
<template #grid="slotProps">
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
</DataView>
Paginator
Pagination is enabled by setting paginator property to true, rows attribute defines the number of rows per page and pageLinks specify the the number of page links to display. To customize the left and right side of the paginators, use paginatorLeft and paginatorRight templates.
<DataView :value="cars" :layout="layout" paginatorPosition="both" :paginator="true" :rows="20">
<template #paginatorLeft>
<Button type="button" icon="pi pi-refresh"/>
</template>
<template #paginatorRight>
<Button type="button" icon="pi pi-search" />
</template>
<template #list="slotProps" >
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
<template #grid="slotProps">
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
</DataView>
Sorting
sortField and sortOrder properties are available for the sorting functionality, for flexibility there is no built-in UI available so that a custom UI can be used for the sorting element. Here is an example that uses a dropdown where simply updating the sortField-sortOrder bindings of the DataView initiates sorting.
<DataView :value="cars" :layout="layout" :sortOrder="sortOrder" :sortField="sortField">
<template #header>
<div class="p-grid p-nogutter">
<div class="p-col-6" style="text-align: left">
<Dropdown v-model="sortKey" :options="sortOptions" optionLabel="label" placeholder="Sort By" @change="onSortChange($event)"/>
</div>
<div class="p-col-6" style="text-align: right">
<DataViewLayoutOptions v-model="layout" />
</div>
</div>
</template>
<template #list="slotProps" >
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
<template #grid="slotProps">
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
</DataView>
export default {
data() {
return {
cars: null,
layout: 'list',
sortKey: null,
sortOrder: null,
sortField: null,
sortOptions: [
{label: 'Newest First', value: '!year'},
{label: 'Oldest First', value: 'year'},
{label: 'Brand', value: 'brand'}
]
}
},
carService: null,
created() {
this.carService = new CarService();
},
mounted() {
this.carService.getCarsLarge().then(data => this.cars = data);
},
methods: {
onSortChange(event){
const value = event.value.value;
const sortValue = event.value;
if (value.indexOf('!') === 0) {
this.sortOrder = -1;
this.sortField = value.substring(1, value.length);
this.sortKey = sortValue;
}
else {
this.sortOrder = 1;
this.sortField = value;
this.sortKey = sortValue;
}
}
}
}
Lazy Loading
Lazy loading is useful to deal with huge datasets, in order to implement lazy loading use the pagination and utilize the page callback to load your data from the backend. Pagination in this case needs to display the logical number of records bound to the totalRecords property so that paginator can display itself according to the total records although you'd only need to load the data of the current page.
<DataView :value="cars" :layout="layout" :paginator="true" :rows="20" :lazy="true" @page="onPage($event)">
<template #list="slotProps" >
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
<template #grid="slotProps">
<div>Vin: <b>{{slotProps.data.vin}}</b></div>
</template>
</DataView>
export default {
data() {
return {
cars: null,
layout: 'list'
}
},
carService: null,
mounted() {
this.cars = //initialize the first chunk of data between 0 and 20
},
methods: {
onPage(event){
this.cars = //load the data between (event.first) and (event.first + event.rows) from a remote datasource
}
}
}
Theming
DataView supports various themes featuring Material, Bootstrap, Fluent as well as your own custom themes via the Designer tool.
Resources
Visit the PrimeVue DataView showcase for demos and documentation.