DEV Community

loading...
Cover image for Vue3 DataView

Vue3 DataView

primetek profile image PrimeTek ・4 min read

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';
Enter fullscreen mode Exit fullscreen mode

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);
    }
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
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;
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode
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
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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.

Discussion (0)

Forem Open with the Forem app