1.4.1 • Published 3 years ago

vue3-easy-table v1.4.1

Weekly downloads
-
License
MIT
Repository
gitlab
Last release
3 years ago

Vue 3 Easy Table

A simple and highly customizable component for creating data tables based on plugins.

preview

View demo

Table of Contents

Installation

NPM

npm install vue3-easy-table --save

Usage

Register globally

First, register the full components in your app entry point (app.js) .

import { createApp} from 'vue'
import App from './App.vue'
import EasyTable from 'vue3-easy.table'
// Import de default theme, or you can create your own custom theme
import 'vue3-easy-table/themes/default.css'
...
createApp(App)
    .use(EasyTable)
    .mount('#app')

Or also you can register components individually.

import { createApp} from 'vue'
import App from './App.vue'
import {
    useEasyDataTable,
    useEasyPaginator,
    useEasySortFilter,
    useEasyTotalizer
} from 'vue3-easy.table'
// Import de default theme, or you can create your own custom theme
import 'vue3-easy-table/themes/default.css'
...
createApp(App)
    .use(useEasyDataTable)
    .use(useEasyPaginator)
    .use(useEasySortFilter)
    .use(useEasyTotalizer)
    .mount('#app')

Next, use it on your template

Basic Example

<template>
	<div class="overflow-x-auto w-full">
        <e-data-table
          :headers="headers"
          :items="items"
          :is-loading="loading">
        </e-data-table>
	</div>
</template>
<script>
export default {
    data() {
        return {
            headers: [
                { label: 'Id', key: 'id'},
                { label: 'Username', key: 'username'},
                { label: 'Full Name', key: 'fullName'},
                { label: 'Amount', key: 'amount', formatter: (value) => `$${value}` },
            ],
            items: [
                { id: 1, username: 'Octavius Rex', fullName: 'Octavius Rex', amount: 1000 },
                { id: 2, username: 'spongebob', fullName: 'Sponge Bob Squarepants', amount: 1500 },
                { id: 3, username: 'patrickstar', fullName: 'Patrick Star', amount: 1020 },
                { id: 4, username: 'sandycheeks', fullName: 'Sandy Cheeks', amount: 800 },
                { id: 5, username: 'eugenekrabs', fullName: 'Eugene H. Krabs', amount: 950 },
                { id: 6, username: 'sheldonplankton', fullName: 'Sheldon J. Plankton', amount: 300 },
            ],
            isLoading: false
        }
    }
}
</script>

<style>
</style>

Advanced Example

<template>
    <div>
        <e-keyword-filter v-model:filtered="filtered" :original="items"></e-keyword-filter>
        <e-data-table
            :headers="headers"
            :items="filtered"
            :is-loading="isLoading"
            :current-page="currentPage"
            v-model:total-items="totalItems"
            :per-page="perPage"
            rowStyle="link"
            @row-click="showUser">

            <template v-slot:header[default]="{ header }">
                {{ header.label }}
                <e-sort-filter :key-param="header.key" v-model:sort-by="sortBy" v-model:sort-desc="sortDesc" v-model:filtered="filtered"/>
            </template>
            <template v-slot:cell[username]="{ cell }">
                <div class="flex items-center">
                    <span>{{ `${cell.item.username}` }}</span>
                </div> 
            </template>
            <template v-slot:footer[amount]="{ footer }">
                <e-totalizer :key-column="footer.key" :items="filtered" :formatter="footer.formatter"/>
            </template>
        </e-data-table>
        <div class="mt-auto">
            <e-paginator v-model:current-page="currentPage" v-model:total-items="totalItems" v-model:per-page="perPage" />
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            headers: [
                { label: 'Id', key: 'id'},
                { label: 'Username', key: 'username'},
                { label: 'Full Name', key: 'fullName'},
                { label: 'Amount', key: 'amount', formatter: (value) => `$${value}` },
            ],
            items: [
                { id: 1, username: 'Octavius Rex', fullName: 'Octavius Rex', amount: 1000 },
                { id: 2, username: 'spongebob', fullName: 'Sponge Bob Squarepants', amount: 1500 },
                { id: 3, username: 'patrickstar', fullName: 'Patrick Star', amount: 1020 },
                { id: 4, username: 'sandycheeks', fullName: 'Sandy Cheeks', amount: 800 },
                { id: 5, username: 'eugenekrabs', fullName: 'Eugene H. Krabs', amount: 950 },
                { id: 6, username: 'sheldonplankton', fullName: 'Sheldon J. Plankton', amount: 300 },
            ],
            filtered: [],
            isLoading: false,
            perPage: 3,
            totalItems: 0,
            currentPage: 1,
            sortBy: 'username',
            sortDesc: false,
        }
    },
    methods: {
        showUser(user) {
            alert(user.fullName)
        }
    }
}
</script>

<style>
</style>

Translation

This feature is still under development and there are still translations to be made, you can configure the language that will be displayed by certain components, to use the component translation you must import the translation file and configure it in the entry point of your application..

import { createApp } from 'vue'
import App from './App.vue'
import EasyTable from 'vue3-easy.table'
// Import de default theme, or you can create your own custom theme
import 'vue3-easy-table/themes/default.css'
import es from 'vue3-easy-table/src/lang/es'

changeLang(es)
...
createApp(App)
    .use(EasyTable)
    .mount('#app')

Configuring the components

Vue3 Easy Table includes components that offer a large number of properties for your configuration.

Data Table

The data table is the main component that displays a table with the data that it receives by parameter.

Data Table Props
headers

Sets an object that allows you to configure the table headers.

type:Array

required:true

/*
* You can configure each header individually.
* label: The label to be displayed in the column header
* username: The name of the item's parameter
* formatter: Optionally you can include a function that formats the value that is passed to the cell
* width: Optinally you can indicate the width of the column on a string, ex: '20%', '50px', '2.5rem'
* aligment: Optionally you can indicate de column aligment on a string, ex: 'left', 'center', 'right'
*/
[
    { label: 'Id', key: 'id', width: '20px'},
    { label: 'Userbaname', key: 'username'},
    { label: 'Full Name', key: 'fullName'},
    { label: 'Amount', key: 'amount', formatter: (value) => `$${value}`, aligment: 'right' },
]
row-style

Specify a function that returns a string with the name of the class to apply depending on what is evaluated within the function, the item of the row is passed as the first parameter of the function.

type: Function

default: (item) => ''

const rowStyle = (item) => item.isDeleted ? 'item-deleted-class' : ''
items

It is the collection of data that wjjkill be iterated in the table.

type: Array

required: true

[
    { id: 1, username: 'Octavius Rex', fullName: 'Octavius Rex', amount: 1000 },
    { id: 2, username: 'spongebob', fullName: 'Sponge Bob Squarepants', amount: 1500 },
    { id: 3, username: 'patrickstar', fullName: 'Patrick Star', amount: 1020 },
    { id: 4, username: 'sandycheeks', fullName: 'Sandy Cheeks', amount: 800 },
    { id: 5, username: 'eugenekrabs', fullName: 'Eugene H. Krabs', amount: 950 },
    { id: 6, username: 'sheldonplankton', fullName: 'Sheldon J. Plankton', amount: 300 },
]
is-loading

Allows you to specify if the table is in loading state or not.

type: Boolean

default: false

isLoading: true
current-page

Indicates the current page number where the pagination is located.

type: Number

default: 1

currentPage: 5 // Show de items in the page 5
per-page

Indicates the number of pages to be displayed in the table.

type: Number

default: 15

perPage: 15
empty-label

The text that will appear in the table when it is empty and there is no slot already applied.

type: String

default: Empty

emptyLabel: 'Empty Table'
Data Table Events

@row-clicked

The event is fired when a row is clicked.

Data Table Slots

You can customize the content within the headers, cells, feet, through the slots.

To refer to a specific slot you can use the syntax:

v-slot:header[headerKey]
v-slot:cell[headerKey]
v-slot:footer[headerKey]

Without wanting to set a slot for everyone you can use the default slot that will be mounted by default

v-slot:header[default]
v-slot:cell[default]
v-slot:footer[default]

You can customize the message that appears when the table is empty with the slot v-slot:cell[empty].

v-slot:cell[default]
<!-- Header template -->
<template v-slot:header[default]="{ header }">
	{{ header.label }}
	<e-sort-filter :key-param="header.key" v-model:sort-by="sortBy" v-model:sort-desc="sortDesc" v-model:items="items"/>
</template>
<!-- Cell template -->
<template v-slot:cell[username]="{ cell }">
	<div class="flex items-center">
        <span>{{ `${cell.item.username}` }}</span>
    </div> 
</template>
<!-- Emtpy template -->
<template v-slot:cell[empty]>
	<div class="flex items-center">
        <span>Empty table</span>
    </div> 
</template>
<!-- Footer template -->
<template v-slot:footer[amount]="{ footer }">
	<e-totalizer :key-column="footer.key" :items="items" :formatter="footer.formatter"/>
</template>
Data Table Theming

You can fully customize the plugin with the classes it includes.

.et-container {
    width: 100%;
    border-style: solid;
    border-width: 1px;
    border-radius: .8rem;
    border-color: #191919;
    overflow: hidden;
}

.et-container .et-table {
    position: relative;
    width: 100%;
    border-collapse: collapse;
}

.et-container .et-table.loading {
    opacity: 50%;
}

.et-container .et-table-header {
    position: sticky;
    top: 0;
    background-color: #e4e3e5; 
}

.et-container .et-table-header-container {
    display: flex;
    padding: 0.2rem 1rem;
    height: 100%;
    justify-content: center;
    align-items: center;
    padding: .2rem 2rem;
}

.et-container .et-table-cell {
    font-size: 1rem;
    text-align: center;
}

.et-container .et-table-body-row.et-table-row-link {
    cursor: pointer;
}

.et-container .et-table-body-row.et-table-row-link:hover {
    background-color: #b5b5b5;
    box-shadow: 0 0 0 0 #333333;
    transition: all .3s ease;
}

.et-container .et-table-cell-container {
    display: flex;
    padding: 1rem 2rem;
}

Keyword Filter

Plugin that allows you to filter the items by a keyword.

Keyword Filter Props
filtered

It must be an empty array that the filter will use as temporary, keep in mind that the collection is not modified instead a copy of the original collection is created.

type: Array

required: true

filtered: []
original

It is the original collection to which the filter is applied.

type: Array

required: true

[
    { id: 1, username: 'Octavius Rex', fullName: 'Octavius Rex', amount: 1000 },
    { id: 2, username: 'spongebob', fullName: 'Sponge Bob Squarepants', amount: 1500 },
    { id: 3, username: 'patrickstar', fullName: 'Patrick Star', amount: 1020 },
]
placeholder

The text to display in the placeholder.

type: String

default: Search

placeholder: 'Search item'
Keyword Filter Theming

You can fully customize the plugin with the classes it includes.

.et-keyword {
    padding: .5rem;
}

.et-keyword .et-keyword-input
{
    padding: .5rem;
    border-radius: .5rem;
    border: none;
}

Sort Filter

Plugin that allows you to sort the items within the array by a given key in ascending or descending order.

Sort Filter Props
filtered

Collection of data that the filter will sort, keep in mind that the filter will modify the original collection.

type: Array

required: true

[
    { id: 1, username: 'Octavius Rex', fullName: 'Octavius Rex', amount: 1000 },
    { id: 2, username: 'spongebob', fullName: 'Sponge Bob Squarepants', amount: 1500 },
    { id: 3, username: 'patrickstar', fullName: 'Patrick Star', amount: 1020 },
]
header

The column header, the filter will look for the meta.isSortable parameter to verify if the column can apply the filter or not, to deactivate the filter in a specific column the value must be false.

type: Object

required: false

/* In the headers object */
[
    { label: 'Id', key: 'id', width: '20px', meta: { isSortable: false }},
    ...
]
key-param

The key of the current column on which the plugin will act.

type: String

required: true

keyParam: 'username'
sort-by

The key of the column by which the plugin should sort.

type: String

required: true

sortBy: 'username'
sort-desc

Direction in which the items should be ordered.

type: Boolean

required: true

sortDesc: true
Sort Filter Slots

You can customize the content of the component such as the ordering buttons in ascending, descending order or when the filter is not applied in that column.

v-slot:neutral-button
v-slot:desc-button
v-slot:desc-button
<!-- Neutral Button template -->
<template #neutral-button>
	<fa-icon icon="sort"/>
</template>
<!-- Desc Button template -->
<template #desc-button>
	<fa-icon icon="sort-down"/>
</template>
<!-- Asc Button template -->
<template #asc-button>
	<fa-icon icon="sort-up"/>
</template>
Sort Filter Theming

You can fully customize the plugin with the classes it includes.

.et-sorter
{
    display: flex;
    justify-content: center;
    margin-left: 1rem;
    margin: 0.2rem 1rem;
    border-radius: .3rem;
    transition: all .3s ease;
    border: none;
    padding: .2rem .5rem;
}

.et-sorter:hover,
.et-sorter:active
{
    background-color: #b5b5b5;
}

.et-sorter.neutral
{
    width: 100%;
    color: #333333;
}

Paginator

Plugin that allows you to control the pagination of a table.

Paginator Props
current-page

Indicates the current page that the component should show as marked.

type: Number

default: 1

currentPage: 1
total-items

The total number of items in the data collection, this data is used so that the plugin can calculate the number of pages.

type: Number

required: true

totalItems: 150
per-page

The number of items displayed per page, the plugin uses this data to calculate the number of pages.

type: Number

required: true

perPage: 15
offset

The maximum number of pages to be displayed.

type: Boolean

default: 5

offset: 5
Paginator Slots

You can customize the paging content such as the forward, backward or go to the page buttons through the slots that it includes.

v-slot:prev
v-slot:page
v-slot:next
<!-- Prev Button template -->
<template #prev>
	<fa-icon icon="angle-left"/>
</template>
<!-- Page Button template -->
<template #page="{ page }">
	<span>{{ page }}</span>
</template>
<!-- Next Button template -->
<template #next>
	<fa-icon icon="angle-right"/>
</template>
Paginator Theming

You can fully customize the plugin with the classes it includes.

.et-paginator
{
    display: flex;
    flex-direction: row-reverse;
}

.et-paginator .et-paginator-container
{
    display: flex;
    margin: 1rem auto;
    border-width: 1px;
    border-style: solid;
    border-color:#333333; 
    border-radius: .3rem;
    overflow: hidden;
}

.et-paginator .nav-button
{
    padding: .2rem 1rem;
    border-right: 1px solid #333333;
    outline: none;
    background-color: transparent;
}

.et-paginator .nav-button.pre
{
    padding: .2rme 1rem;
    border-right: 1px solid #333333;
    outline: none
}

.et-paginator .nav-button.next
 {
     border: none;
}

.et-paginator .nav-button:hover {
    background-color: #b5b5b5;
}

 .et-paginator .nav-button.active {
    background-color: #05308c;
    color: white;
    border: 1px solid #05308c;
}

Totalizer

Complement that calculates the total, of a column, keep in mind that if there are other filters applied, all the filtered items will be added.

Totalizer Props
key-column

The key of the column to be totaled.

type: String

required: true

keyColumn: 'amount'
items

The filtered data collection.

type: Array

required: true

[
    { id: 1, username: 'Octavius Rex', fullName: 'Octavius Rex', amount: 1000 },
    { id: 2, username: 'spongebob', fullName: 'Sponge Bob Squarepants', amount: 1500 },
    { id: 3, username: 'patrickstar', fullName: 'Patrick Star', amount: 1020 },
]
formatter

The formatting function that will be applied to the footer.

type: Function

required: false

formatter: (value) => value.toLowerCase()
Totalizer Theming

You can fully customize the plugin with the classes it includes.

.et-totalizer {
    font-weight: bold;
    text-align: center;
}

Page Number

Add-in that displays table information such as total number of records, current page, and number of pages in the table..

Page Number Props
current-page

Indicates the current page that the component should show.

type: Number

default: 1

currentPage: 1
total-items

The total number of items in the data collection, this data is used so that the plugin can calculate the number of pages.

type: Number

required: true

totalItems: 150
per-page

The number of items displayed per page, the plugin uses this data to calculate the number of pages.

type: Number

required: true

perPage: 15
Page Number Theming

You can fully customize the plugin with the classes it includes.

.et-page-number { /* Wrapper */ }
.et-totalizer .et-total-items { /* Label that show de total items */ }
.et-totalizer .et-pipe-separator { /* Separator caracter */ }
.et-totalizer .et-current-page { /* Label that show de current page */ }
.et-totalizer .et-page-separator { /* Separator page normally "of" */ }
.et-totalizer .et-total-pages { /* Label that show de total pages */ }
1.4.1

3 years ago

1.4.0

3 years ago

1.3.2

3 years ago

1.3.1

3 years ago

1.2.0

3 years ago

1.3.0

3 years ago

1.2.1

3 years ago

1.1.2

3 years ago

1.1.1

3 years ago

1.1.0

3 years ago

1.0.0

3 years ago