The vue-dataset library provides a set of components that allows you to filter, sort, and paginate any data (like lists, cards, tables) in Vue applications.
Basic Usage:
1. Import components into your app.
import { Dataset, DatasetItem, DatasetInfo, DatasetPager, DatasetSearch, DatasetShow } from 'vue-dataset';
2. The example shows how to filter, sort, and paginate datasets in a card layout.
<template> <div> <h3>Custom filters</h3> <div class="row mb-1"> <div class="col-md-6 mb-2 mb-md-0"> <div class="btn-group"> <button type="button" class="btn btn-outline-secondary" :class="[onlineFilter === '' && 'active']" @click.prevent="onlineFilter = ''"> <span class="badge bg-white text-secondary">{{ users.length }}</span> All </button> <button type="button" class="btn btn-outline-secondary" :class="[onlineFilter === 'Active' && 'active']" @click.prevent="onlineFilter = 'Active'"> <span class="badge bg-success text-white">{{ filterList(users, {'onlineStatus': 'Active'}).length }}</span> Active </button> <button type="button" class="btn btn-outline-secondary" :class="[onlineFilter === 'Away' && 'active']" @click.prevent="onlineFilter = 'Away'"> <span class="badge bg-warning text-white">{{ filterList(users, {'onlineStatus': 'Away'}).length }}</span> Away </button> <button type="button" class="btn btn-outline-secondary" :class="[onlineFilter === 'Do not disturb' && 'active']" @click.prevent="onlineFilter = 'Do not disturb'"> <span class="badge bg-danger text-white">{{ filterList(users, {'onlineStatus': 'Do not disturb'}).length }}</span> Do not disturb </button> <button type="button" class="btn btn-outline-secondary" :class="[onlineFilter === 'Invisible' && 'active']" @click.prevent="onlineFilter = 'Invisible'"> <span class="badge bg-secondary text-white">{{ filterList(users, {'onlineStatus': 'Invisible'}).length }}</span> Invisible </button> </div> </div> <div class="col-md-6"> <input type="text" class="form-control" placeholder="Name starts with" @input="startWithInput($event)"> </div> </div> <hr class="mb-1" /> <h3>Sorting</h3> <div class="row mb-2"> <div class="col-md-6 mb-2 mb-md-0"> <button type="button" class="btn btn-outline-secondary" @click="firstNameAsc = !firstNameAsc">First name {{ firstNameAsc ? 'asc' : 'desc' }}</button> </div> </div> <hr /> <dataset v-slot="{ ds }" :ds-data="users" :ds-filter-fields="{ onlineStatus: onlineFilter, name: startsWithFilter }" :ds-sortby="[sortFirstName]" :ds-search-in="['balance', 'birthdate', 'name', 'company', 'email', 'phone', 'address', 'favoriteAnimal']" :ds-search-as="{ birthdate: searchAsEuroDate }" > <div class="row mb-2"> <div class="col-md-6 mb-2 mb-md-0"> <dataset-show /> </div> <div class="col-md-6"> <dataset-search ds-search-placeholder="Search..." :wait="300" /> </div> </div> <div class="row"> <div class="col-md-12"> <dataset-item class="form-row mb-3" style="overflow-y: auto; max-height: 400px;"> <template v-slot="{ row, rowIndex }"> <div class="col-md-4"> <div class="card mb-2"> <div class="card-body pt-3 pb-2 px-3"> <h5 class="card-title text-truncate mb-2" :title="`Index: ${ rowIndex }`"> <span :class="['font-16', statusClass[row.onlineStatus]]">⬤</span> {{ row.name }} </h5> <h6 class="card-subtitle text-truncate text-muted">{{ row.email }}</h6> <p class="card-text text-truncate mb-0">{{ row.balance }}</p> <p class="card-text text-truncate text-right">{{ isoDateToEuroDate(row.birthdate) }}</p> </div> </div> </div> </template> <template v-slot:noDataFound> <div class="col-md-12 pt-2"> <p class="text-center">No results found</p> </div> </template> </dataset-item> </div> </div> <div class="d-flex flex-md-row flex-column justify-content-between align-items-center"> <dataset-info class="mb-2 mb-md-0" /> <dataset-pager /> </div> </dataset> </div> </template>
export default { name: 'Example', data: function () { return { users: users, startsWith: '', onlineFilter: '', statusClass: { Active: 'text-success', Away: 'text-warning', 'Do not disturb': 'text-danger', Invisible: 'text-secondary' }, firstNameAsc: true }; }, computed: { sortFirstName () { return this.firstNameAsc ? 'firstName' : '-firstName'; } }, created () { this.startWithInput = debounce((e) => { this.startsWith = e.target.value; }, 300); }, methods: { filterList, isoDateToEuroDate, searchAsEuroDate, updateData () { const updatedUsers = clone(users).slice(5, 10); this.users = updatedUsers; }, startsWithFilter (value) { return value.toLowerCase().startsWith(this.startsWith.toLowerCase()); } } };
3. This example shows to how create a data table.
<template> <div> <dataset v-slot="{ ds }" :ds-data="users" :ds-sortby="sortBy" :ds-sort-as="{ birthdate: isoDateToDate }" :ds-search-in="['balance', 'birthdate', 'name', 'company', 'email', 'phone', 'address', 'favoriteAnimal']" :ds-search-as="{ birthdate: searchAsEuroDate }" > <div class="row"> <div class="col-md-6 mb-2 mb-md-0"> <dataset-show /> </div> <div class="col-md-6"> <dataset-search ds-search-placeholder="Search..." :wait="300" /> </div> </div> <div class="row"> <div class="col-md-12"> <div class="table-responsive"> <table class="table table-striped d-md-table"> <thead> <tr> <th scope="col">#</th> <th v-for="(th, index) in cols" :key="th.field" :class="['sort', th.sort]" @click="click($event, index)"> {{ th.name }} <i class="gg-select float-right"></i> </th> </tr> </thead> <dataset-item tag="tbody"> <template v-slot="{ row, rowIndex }"> <tr> <th scope="row">{{ rowIndex + 1 }}</th> <td>{{ row.name }}</td> <td>{{ row.email }}</td> <td>{{ isoDateToEuroDate(row.birthdate) }}</td> </tr> </template> </dataset-item> </table> </div> </div> </div> <div class="d-flex flex-md-row flex-column justify-content-between align-items-center"> <dataset-info class="mb-2 mb-md-0" /> <dataset-pager /> </div> </dataset> </div> </template>
export default { name: 'Example', data: function () { return { users: users, cols: [ { name: 'Name', field: 'name', sort: '' }, { name: 'Email', field: 'email', sort: '' }, { name: 'Birthdate', field: 'birthdate', sort: '' } ] }; }, computed: { sortBy () { return this.cols.reduce((acc, o) => { if (o.sort) { o.sort === 'asc' ? acc.push(o.field) : acc.push('-' + o.field); } return acc; }, []); } }, methods: { click (event, i) { let toset; const sortEl = this.cols[i]; if (!event.shiftKey) { this.cols.forEach(o => { if (o.field !== sortEl.field) { o.sort = ''; } }); } if (!sortEl.sort) { toset = 'asc'; } if (sortEl.sort === 'desc') { toset = event.shiftKey ? '' : 'asc'; } if (sortEl.sort === 'asc') { toset = 'desc'; } sortEl.sort = toset; }, isoDateToEuroDate, isoDateToDate, searchAsEuroDate } };
Preview:
Changelog:
v1.1.18 (08/31/2023)
- bugfixes
v1.1.17 (11/06/2022)
- bugfixes
v1.1.16 (08/07/2022)
- fixed set active page to last page
v1.1.15 (07/18/2022)
- fixed table spacing
v1.1.14 (06/12/2022)
- Bug Fixes
v1.1.13 (04/20/2022)
- Bug Fixes
v1.1.12 (01/22/2022)
- Bug Fixes
v1.1.10/11 (01/08/2022)
- Bug Fixes
v1.1.9 (09/27/2021)
- fix: added iteration index
v1.1.8 (09/19/2021)
- Bug Fixes
v1.1.7 (08/09/2021)
- Bug Fixes
v1.1.6 (08/05/2021)
- Bug Fixes
v1.1.5 (07/24/2021)
- Bug Fixes
v1.1.2 (05/07/2021)
- Update
Download Details:
Author: kouts
Live Demo: https://vue-dataset-demo.netlify.app/examples/cards/
Download Link: https://github.com/kouts/vue-dataset/archive/refs/heads/master.zip
Official Website: https://github.com/kouts/vue-dataset
Install & Download:
# NPM
$ npm i vue-dataset