tablevu

Vue 3 data table component
2,726
Install
npm install tablevu
Latest Version:0.3.2
Vue:3
License:MIT
Last Updated:Nov 15, 2021
Links: GitHub  ·  npm
Maintainer: enbz

TableVu

TableVu is a Vue 3 table component with local-array and adapter-backed data loading. It supports paging, sorting, search, filtering, grouping, custom cell rendering, and OData requests.

Interactive example

The Northwind example demonstrates search, country and OData filters, paging, column interactions, and grouping by either a field or a function. To run it locally, use the commands below from this package directory. The browser needs internet access for Vue and the Northwind OData service.

npm install
npm run build
python3 -m http.server 8080

Open http://localhost:8080/example/test-northwind.html.

The npm package page renders this README as GitHub Flavored Markdown; it does not run embedded HTML or JavaScript. To offer a live demo, publish the static example/ page and dist/ bundle with GitHub Pages, then link to that hosted page here. GitHub Pages can serve static HTML, CSS, and JavaScript from a repository. See npm README documentation and GitHub Pages documentation.

Install

npm install tablevu vue

Vue is a peer dependency and must be installed by the application.

Quick start

<script setup lang="ts">
import { ref } from 'vue';
import { TableVu } from 'tablevu';
import type { TableVuExpose } from 'tablevu';

const table = ref<TableVuExpose | null>(null);
const search = ref('');
const rows = [
  { id: 1, name: 'Ada Lovelace', city: 'London' },
  { id: 2, name: 'Grace Hopper', city: 'New York' },
  { id: 3, name: 'Katherine Johnson', city: 'White Sulphur Springs' }
];
const settings = {
  page: { size: 10 },
  columns: [
    { name: 'id', label: 'ID', type: 'integer', width: '5rem' },
    { name: 'name', label: 'Name', searchable: true },
    { name: 'city', label: 'City' }
  ]
};
</script>

<template>
  <input v-model="search" placeholder="Search">
  <TableVu
    ref="table"
    :data="rows"
    :settings="settings"
    :search="search"
  />
</template>

Passing an array directly uses the built-in local adapter. Pass an adapter function such as odata(...) for remote data. The component requests its first page when mounted.

Component props

Prop Type Description
data any[] | AdapterFunction Local rows or an async adapter.
settings TablevuSettings Columns and table behavior.
group string | TablevuGroup Group configuration. settings.group is also supported.
search string Search text. The component refreshes after a short debounce.
filter any Adapter-specific filter value; changing it reloads data.
command { name, page? }[] Append a command (refresh, first, prior, next, last, or go) to trigger an action.
rowid string Row property copied to the rendered row's rowid attribute.
onRowClick (event, row) => void Row click callback.
onRowDblClick (event, row) => void Row double-click callback.
class string Additional table CSS class.
style string | Record<string, string> Inline table style.

The component also emits row-click and row-dbl-click, each with (event, row) arguments.

Settings

const settings = {
  page: { size: 20 },
  sort: [{ name: 'name', dir: 'asc' }],
  searchMinChar: 2,
  emptyMessage: 'No matching records',
  footer: { button: { class: 'pager-button' } },
  columns: [
    { name: 'name', label: 'Name', width: '16rem', resizable: true, draggable: true },
    { name: 'address.city', label: 'City', type: 'string' }
  ]
};

Columns

Option Description
name Required field name. Dotted paths such as address.city are supported.
label Header label; defaults to name.
type string, number, numeric, integer, date, time, datetime, or boolean. Date/time values are formatted using the browser locale.
align Cell alignment: left, center, or right.
width CSS width applied to header and cells.
style Inline cell style object.
render (row) => VNodeChild callback for custom cell content.
colspan Cell column span.
searchable Set to false to exclude the column from search.
resizable Set to false to disable drag resizing.
draggable Set to false to disable header dragging.
visible Column metadata; columns marked invisible are not currently filtered out by the renderer.
popup Show a header menu with ascending and descending sort actions.
depth, header, filter Additional metadata fields; filter UI is not implemented.

Headers sort when clicked. Drag a header to reorder it; drag it outside the table to remove it from the current table instance. Drag the right edge to resize it. These interactions update the component's in-memory column state; they are not persisted automatically.

searchMinChar controls the search threshold (default 3); search runs when the input length is greater than this value. Search is debounced. For arrays, search checks configured searchable columns locally. The OData adapter builds a contains filter across searchable columns.

Grouping

Set group.value to a field name or a function of each row. content independently chooses the displayed group heading. expandAll defaults to true; class sets the group row's CSS class.

const fieldGroup = {
  value: 'country',
  content: 'country',
  expandAll: true,
  class: 'country-group'
};

const functionGroup = {
  value: (row: { country: string }) => row.country.toUpperCase(),
  content: (row: { country: string }) => `Country: ${row.country}`
};

The component uses the first row in each group to calculate its displayed content. Grouping is performed on the rows returned for the current page.

Adapter data hook

settings.onData(rows) can transform each page of adapter results before rendering. It must return the rows to display.

Adapters

An adapter receives paging, sort, columns, filter, and search information and returns { rows, count }:

import type { AdapterFunction } from 'tablevu';

const loadRows: AdapterFunction = async ({ pageSize, currPage, sort, cols, filter, search }) => {
  // Fetch/transform rows using the received parameters.
  return { rows: [], count: 0 };
};

count is the total number of rows matching the query, not just the returned page. It is used to calculate the page count. adaptArray implements local equality filters, search, sorting, and paging. Its filter is a key/value object, for example { status: 'active' }.

OData adapter

odata(options) creates an adapter that uses fetch, adds OData query parameters, and expects a JSON response with a value array and optional @odata.count.

import { odata } from 'tablevu';

const loadCustomers = odata({
  url: 'https://services.odata.org/V4/Northwind/Northwind.svc/Customers',
  count: true,
  select: ['CustomerID', 'CompanyName', 'Country'],
  expand: [{ name: 'Orders', select: ['Freight', 'ShipCountry'] }],
  filter: { column: 'Country', operator: 'ne', value: 'USA' }
});

Options:

Option Description
url Required collection endpoint.
select $select fields.
expand $expand entries with name, optional select, filter, and orderby.
filter Static OData filter expression or typed Filter.
count Request $count=true.
headers Fetch request headers.
credentials Fetch credentials mode.
fetch Custom fetch implementation.
onfetch Request hook; return the request to send.

The adapter also uses the component's current page, sort, search, and filter prop to build $skip, $top, $orderby, and $filter parameters. Pass the adapter to TableVu through :data="loadCustomers".

OData filters

import type { Filter } from 'tablevu';

const filter: Filter = {
  operator: 'and',
  filters: [
    { column: 'Country', operator: 'in', value: ['Germany', 'France'] },
    { column: 'CompanyName', operator: 'contains', value: 'market' },
    { column: 'Orders', operator: 'any', variable: 'order',
      filter: { column: 'Freight', operator: 'gt', value: 100 } }
  ]
};

Supported operators: eq, ne, gt, ge, lt, le, contains, startsWith, endsWith, in, between, isNull, isNotNull, and, or, not, any, all, countGt, countGe, countLt, and countLe. Use field or column for the property name; dotted paths become OData slash paths. and/or take filters; not takes one child; any/all take a nested filter and optional variable (default item). Count operators compare a collection's $count with a non-negative integer. String filters are passed through as raw OData expressions.

Filter is an OData filter type. The built-in array adapter currently supports simple equality maps rather than this OData filter tree.

Template ref methods

interface TableVuExpose {
  first(): Promise<void>;
  prior(): void | Promise<void>;
  next(): void | Promise<void>;
  last(): void | Promise<void> | undefined;
  go(pageNumber: number): void | Promise<void>;
  page(pageNumber: number): Promise<void>;
  refresh(): Promise<void>;
  sortBy(columnIndex: number, direction?: string): void | Promise<void>;
  getRows(): any[];
  setRows(rows: any[]): void;
}

go() validates positive integer page numbers and clamps to the known last page. page() reloads a specified page directly. getRows() returns the currently rendered page; setRows() replaces those displayed rows.

TypeScript exports

The package exports TableVu, odata, buildFilter, adaptArray, and the public types including TableVuExpose, TablevuSettings, TablevuColumn, TablevuGroup, AdapterFunction, AdapterParams, AdapterResult, Filter, FilterOperator, and ODataOptions.

Related Packages

vue2-datatable-component

The best Datatable for Vue.js 2.x which never sucks

37,016 870
@unicorns/data-table

Vue component for rendering data-tables

12,383 3
vue2-datatable-component-uikit

The best Datatable for Vue.js 2.x which never sucks... with ui-kit

4,771 870
@laraveldaily/vue2-datatable

Datatable for Vue.js 2.x

3,285 6
vue-datatable-component

Datatable encapsulation for Vue 1.x

646 23

Version History

Version Released License
0.3.2 MIT
0.3.1 MIT
0.3.0 MIT
0.2.22 MIT
0.2.21 MIT
Pre-releases (6)
Version Released License
0.3.0-beta.5 MIT
0.3.0-beta.4 MIT
0.3.0-beta-4 MIT
0.3.0-beta.3 MIT
0.3.0-beta.2 MIT