Data

DataTable

Tabella dati avanzata con supporto per ordinamento, filtri, paginazione, selezione righe, espansione e raggruppamento. Il sub-componente Column definisce le colonne in modo dichiarativo.

Import

import { DataTable, Column } from '@pzeta/vue-components'
import type {
  DataTableProps,
  DataTableEmits,
  DataTableFilterMeta,
  DataTableSortMeta,
  ColumnProps,
} from '@pzeta/vue-components'

Esempio Base

Props — DataTable

PropTipoDefaultDescrizione
valueT[][]Array di dati da visualizzare
dataKeystring'id'Campo che identifica univocamente ogni riga
loadingbooleanfalseMostra indicatore di caricamento
loadingIconstringundefinedIcona di caricamento custom
lazybooleanfalseAbilita lazy loading (paginazione/sort/filter server-side)
stripedRowsbooleanfalseRighe alternate con sfondo diverso
showGridlinesbooleanfalseMostra linee di separazione celle
size'small' | 'medium' | 'large''medium'Dimensione del componente
showHeaderbooleantrueMostra l'intestazione della tabella
rowHoverbooleantrueEvidenzia riga al passaggio del mouse
tableClassstringClasse CSS aggiuntiva per la tabella
tableStylestring | Record<string, string | number>Stile inline per la tabella
scrollablebooleanfalseAbilita scroll orizzontale/verticale
scrollHeightstring'400px'Altezza area di scroll
virtualScrollerOptionsRecord<string, unknown>Opzioni del virtual scroller
sortFieldstringCampo di ordinamento iniziale
sortOrder1 | -1 | 0 | nullnullDirezione ordinamento (1=asc, -1=desc)
multiSortMetaSortMeta[]Metadati per ordinamento multi-colonna
sortMode'single' | 'multiple''single'Modalità ordinamento
removableSortbooleanfalsePermette di rimuovere l'ordinamento con un terzo click
paginatorbooleanfalseAbilita la paginazione
rowsnumber10Numero di righe per pagina
firstnumber0Indice della prima riga visualizzata
totalRecordsnumberNumero totale di record (necessario in lazy mode)
rowsPerPageOptionsnumber[][10, 25, 50]Opzioni per il dropdown righe per pagina
pageLinkSizenumber5Numero di link pagina da mostrare
paginatorPosition'top' | 'bottom' | 'both''bottom'Posizione del paginatore
alwaysShowPaginatorbooleantrueMostra paginatore anche con una sola pagina
currentPageReportTemplatestring'Showing {first} to {last} of {totalRecords} entries'Template report pagina corrente
filtersFilterMetaFiltri attivi (v-model:filters)
filterDisplay'menu' | 'row''menu'Modalità visualizzazione filtri
globalFilterFieldsstring[]Campi inclusi nel filtro globale
selectionT | T[]Righe selezionate (v-model:selection)
selectionMode'single' | 'multiple' | 'checkbox'undefinedModalità selezione righe
metaKeySelectionbooleantrueRichiede Ctrl/Meta per selezione multipla
compareSelectionBy'equals' | 'deepEquals'Metodo di confronto per la selezione
selectAllbooleanStato checkbox header (v-model:selectAll)
expandedRowsT[]Righe espanse (v-model:expandedRows)
expandedRowIconstringIcona riga espansa
collapsedRowIconstringIcona riga collassata
editMode'cell' | 'row'Modalità editing inline
editingRowsT[]Righe in fase di modifica (v-model:editingRows)
rowGroupMode'subheader' | 'rowspan'Modalità raggruppamento righe
groupRowsBystring | string[]Campo per raggruppamento
expandableRowGroupsbooleanGruppi espandibili
expandedRowGroupsunknown[]Chiavi gruppi espansi (v-model:expandedRowGroups)
resizableColumnsbooleanfalseAbilita ridimensionamento colonne
columnResizeMode'fit' | 'expand''fit'Modalità ridimensionamento
reorderableColumnsbooleanfalseAbilita riordinamento colonne tramite drag
contextMenubooleanAbilita menu contestuale al right-click
contextMenuSelectionTRiga selezionata via context menu (v-model:contextMenuSelection)
frozenValueT[]Righe fisse in cima alla tabella
frozenColumnsnumberNumero di colonne frozen a sinistra
stateStorage'session' | 'local'Storage per persistenza stato
stateKeystringChiave univoca per lo stato salvato
responsiveLayout'scroll' | 'stack''scroll'Comportamento responsive
breakpointstring'768px'Breakpoint per layout stack
csvSeparatorstring','Separatore CSV per export
exportFilenamestring'download'Nome file per export CSV
emptyMessagestringTesto mostrato quando non ci sono dati
rowClassstring | ((data: T) => string)Classe CSS dinamica per riga
rowStyleRecord<string, string | number> | ((data: T) => Record<string, string | number>)Stile inline dinamico per riga

Props — Column

PropTipoDefaultDescrizione
fieldstringCampo dati della colonna
headerstringTesto intestazione
footerstringTesto footer
columnKeystringChiave univoca se field non è definito
dataType'string' | 'number' | 'date' | 'boolean' | 'custom'Tipo dato (determina allineamento automatico)
sortablebooleanfalseAbilita ordinamento su questa colonna
sortFieldstringCampo usato per l'ordinamento (default: field)
filterFieldstringCampo usato per il filtro (default: field)
filterMatchModestringModalità di match per il filtro (attiva la colonna filtrabile)
hiddenbooleanfalseNasconde la colonna
widthstringLarghezza colonna (es. '200px', '20%')
minWidthstringLarghezza minima
maxWidthstringLarghezza massima
frozenbooleanfalseColonna fissa (frozen)
alignFrozen'left' | 'right''left'Lato della colonna frozen
expanderbooleanfalseLa colonna mostra il pulsante di espansione riga
rowReorderbooleanfalseLa colonna abilita drag-and-drop riordinamento righe
rowReorderIconstringIcona per il drag handle del riordinamento
reorderableColumnbooleanPermette di riordinare questa colonna
rowEditorbooleanfalseLa colonna mostra i controlli di editing riga
selectionMode'single' | 'multiple' | 'checkbox'Rende questa colonna la colonna di selezione
exportablebooleantrueInclude la colonna nell'export CSV
exportHeaderstringHeader usato nell'export CSV
exportFooterstringFooter usato nell'export CSV
alignHeader'left' | 'center' | 'right''left'Allineamento intestazione
alignBody'left' | 'center' | 'right'Allineamento celle body (default: automatico da dataType)
stylestring | Record<string, string | number>Stile cella
classstring | Record<string, unknown>Classe CSS cella
headerStylestring | Record<string, string | number>Stile intestazione
headerClassstring | Record<string, unknown>Classe intestazione
bodyStylestring | Record<string, string | number>Stile body
bodyClassstring | Record<string, unknown>Classe body
footerStylestring | Record<string, string | number>Stile cella footer
footerClassstring | Record<string, unknown>Classe cella footer
aggregate'sum' | 'count' | 'avg' | 'min' | 'max' | ((rows: T[]) => unknown)Aggregazione built-in da renderizzare nel footer della colonna. Calcolata su paginatedData (record visibili dopo filtri/paginazione). Lo slot #footer ha priorità su aggregate
aggregateFormat(value: unknown) => stringFunzione di formattazione del valore aggregato (es. valuta)
colspannumberColspan per raggruppamento celle
rowspannumberRowspan per raggruppamento celle
excludeGlobalFilterbooleanfalseEsclude la colonna dal filtro globale
showFilterMenubooleantrueMostra menu filtro
showFilterOperatorbooleantrueMostra selector operatore filtro
showClearButtonbooleanfalseMostra pulsante reset filtro
showApplyButtonbooleantrueMostra pulsante applica filtro
showFilterMatchModesbooleantrueMostra selector match modes nel menu filtro
filterMatchModeOptionsFilterMatchModeOption[]Opzioni custom per match modes
showAddButtonbooleantrueMostra pulsante per aggiungere un constraint filtro
maxConstraintsnumber2Numero massimo di filtri per colonna
filterHeaderStylestring | Record<string, string | number>Stile cella header filtro
filterHeaderClassstring | Record<string, unknown>Classe cella header filtro
filterMenuStylestring | Record<string, string | number>Stile menu filtro
filterMenuClassstring | Record<string, unknown>Classe menu filtro

Emits

EventoPayloadDescrizione
update:firstnumberCambio indice prima riga (paginazione)
update:rowsnumberCambio righe per pagina
update:sortFieldstringCambio campo di ordinamento
update:sortOrderSortOrderCambio direzione ordinamento
update:multiSortMetaSortMeta[]Cambio metadati multi-sort
update:selectionT | T[]Cambio selezione righe
update:filtersFilterMetaCambio filtri attivi
update:expandedRowsT[]Cambio righe espanse
update:selectAllbooleanCambio stato "seleziona tutto"
update:expandedRowGroupsunknown[]Cambio gruppi espansi
update:editingRowsT[]Cambio righe in editing
update:contextMenuSelectionTCambio selezione context menu
pagePageEventCambio pagina
sortSortEventCambio ordinamento
filterFilterEventApplicazione filtro
rowClickRowClickEvent<T>Click su una riga
rowDblclickRowClickEvent<T>Doppio click su una riga
rowSelectRowSelectEvent<T>Riga selezionata
rowUnselectRowSelectEvent<T>Riga deselezionata
rowSelectAll{ originalEvent: Event; data: T[] }Selezionate tutte le righe
rowUnselectAll{ originalEvent: Event }Deselezionate tutte le righe
rowExpand{ data: T }Riga espansa
rowCollapse{ data: T }Riga collassata
rowContextmenu{ originalEvent: MouseEvent; data: T; index: number }Right-click su riga
columnReorder{ dragIndex: number; dropIndex: number; columns: unknown[] }Colonne riordinate
rowReorder{ dragIndex: number; dropIndex: number; value: T[] }Righe riordinate via drag
columnResize{ element: HTMLElement; delta: number }Colonna ridimensionata
cellEditInit{ data: T; field: string; index: number }Inizio editing cella
cellEditComplete{ data: T; field: string; newValue: unknown; index: number }Editing cella completato
cellEditCancel{ data: T; field: string; index: number }Editing cella annullato
rowEditInit{ data: T; index: number }Inizio editing riga
rowEditSave{ data: T; newData: T; index: number }Editing riga salvato
rowEditCancel{ data: T; index: number }Editing riga annullato
rowgroupExpand{ originalEvent: Event; data: unknown }Gruppo espanso
rowgroupCollapse{ originalEvent: Event; data: unknown }Gruppo collassato
stateSave{ state: TableState }Stato salvato
stateRestore{ state: TableState }Stato ripristinato
valueChangeT[]Dati processati cambiati

Slot — DataTable

SlotScopeDescrizione
defaultPosizione per i componenti Column
headerContenuto sopra la tabella
footerRiga footer full-width sotto la tabella (renderizzata come <td colspan> unico). Convive con i footer per-Column
table-footerSlot passato a BaseTable per contenuto sotto il body (sopra il paginator bottom)
emptyTemplate per stato vuoto (nessun dato)
loadingTemplate per stato di caricamento
expansion{ data: T; index: number }Contenuto riga espansa
groupheader{ data: T[]; value: unknown; expanded: boolean }Header gruppo righe
groupfooter{ data: T[]; value: unknown }Footer gruppo righe
rowgrouptogglericon{ expanded: boolean }Icona toggle del gruppo righe espandibile
paginatorstartContenuto a sinistra del paginatore
paginatorendContenuto a destra del paginatore
paginatorcontainerPaginatorContainerPropsContainer paginatore completamente custom
paginatorfirstpagelinkicon{ class: string }Icona "prima pagina"
paginatorprevpagelinkicon{ class: string }Icona "pagina precedente"
paginatornextpagelinkicon{ class: string }Icona "pagina successiva"
paginatorlastpagelinkicon{ class: string }Icona "ultima pagina"
paginatorrowsperpagedropdownicon{ class: string }Icona dropdown righe per pagina
paginatorjumptopagedropdownicon{ class: string }Icona dropdown jump-to-page
loadingiconIcona loading custom
reorderindicatorupiconIndicatore reorder colonna (su)
reorderindicatordowniconIndicatore reorder colonna (giù)
rowreorderindicatorupiconIndicatore reorder riga (su)
rowreorderindicatordowniconIndicatore reorder riga (giù)
body-{field}{ data: T; field: string; index: number; column: ColumnProps }Template body per campo specifico (alternativa agli slot di Column)

Slot — Column

SlotScopeDescrizione
body{ data: T; field: string; index: number; column: ColumnProps }Template cella body
header{ column: ColumnProps }Template intestazione
footer{ column: ColumnProps; value: unknown }Template footer per-colonna. value è il risultato dell'aggregazione (o undefined se aggregate non è configurato). Lo slot ha priorità su aggregate e prop footer
filter{ field: string; filterModel: unknown; filterCallback: () => void }Template filtro custom
editor{ data: T; field: string; index: number; editorCallback: (value: unknown) => void }Template editor inline
loadingTemplate loading custom per virtual scroll
sorticon{ sorted: boolean; sortOrder: number | null }Icona sort custom
filtericonIcona menu filtro
filtercleariconIcona clear filtro
filterapplyiconIcona apply filtro
filteraddiconIcona add filtro
filterremoveiconIcona remove filtro
rowreordericonIcona handle reorder riga
rowtoggleicon{ expanded: boolean }Icona toggle expander riga

Esempi

Ordinamento

Filtri per riga

Selezione righe

Espansione riga

Ogni Column può definire uno slot #footer per-colonna, una prop footer: string testuale, oppure una prop aggregate che produce un'aggregazione built-in (sum, count, avg, min, max) o una funzione custom (rows) => unknown. Le aggregazioni vengono calcolate sui dati della pagina corrente (paginatedData, già filtrati e paginati). Lo slot #footer ha priorità su aggregate, che a sua volta vince sulla prop footer. Se nessuna colonna definisce contenuto footer, il <tfoot> non viene renderizzato (backward-compatible).

Regole di priorità per la cella footer (alta → bassa):

  1. Slot #footer="{ column, value }" definito sulla Column
  2. Prop aggregate (con eventuale aggregateFormat)
  3. Prop footer: string (testo statico)
  4. Cella vuota

Funzioni di aggregazione built-in:

Valore aggregateComportamento
'sum'Somma dei valori numerici del field (ignora null/undefined/NaN)
'count'Numero di righe con valore non null/undefined nel field
'avg'Media dei valori numerici del field (0 se vuoto)
'min'Minimo dei valori numerici del field (undefined se vuoto)
'max'Massimo dei valori numerici del field (undefined se vuoto)
(rows: T[]) => unknownFunzione custom che riceve le righe della pagina corrente

Lo slot footer del DataTable (riga full-width colspan) può coesistere con i footer per-Column: viene renderizzata come riga separata dopo quella per-colonna.

Lazy Loading (server-side)

<script setup lang="ts">
import { ref } from 'vue'
import type { DataTablePageEvent, DataTableSortEvent } from '@pzeta/vue-components'

const products = ref<Product[]>([])
const totalRecords = ref(0)
const loading = ref(false)

async function loadData(event: DataTablePageEvent) {
  loading.value = true
  const { data, total } = await fetchProducts({
    first: event.first,
    rows: event.rows,
  })
  products.value = data
  totalRecords.value = total
  loading.value = false
}
</script>

<template>
  <DataTable
    :value="products"
    :total-records="totalRecords"
    :loading="loading"
    :lazy="true"
    :paginator="true"
    :rows="10"
    @page="loadData"
    @sort="loadData"
  >
    <Column field="name" header="Nome" :sortable="true" />
    <Column field="price" header="Prezzo" :sortable="true" data-type="number" />
  </DataTable>
</template>

Editing inline (cell mode)

Allineamento automatico per dataType

L'allineamento delle celle body viene determinato automaticamente dal dataType se alignBody non è specificato esplicitamente:

dataTypeAllineamento body
stringsinistra
numberdestra
datecentro
booleancentro

L'header è sempre allineato a sinistra per default. Usa alignHeader e alignBody per override esplicito.

Metodi esposti (defineExpose)

Accessibili via templateRef.value.* quando si ottiene un ref al DataTable.

Metodo / ProprietàDescrizione
onFilter(field, value, matchMode?)Applica programmaticamente un filtro su una colonna
getFilterValue(field)Restituisce il valore del filtro corrente per il campo
hasActiveFilter(field)Verifica se una colonna ha un filtro attivo
clearFilter(field)Rimuove il filtro di una colonna
clearAllFilters()Rimuove tutti i filtri attivi
processedDataComputed con i dati dopo filtro e ordinamento (tutta la tabella)
paginatedDataComputed con i dati della pagina corrente
isCellEditing(rowKey, field)True se la cella è in editing
isRowEditing(row)True se la riga è in editing
onCellEditInit(data, field, index)Inizia l'editing di una cella
onCellEditComplete(data, field, newValue, index)Completa l'editing di una cella
onCellEditCancel(data, field, index)Annulla l'editing di una cella
onRowEditInit(data, index)Inizia l'editing di una riga
onRowEditSave(data, newData, index)Salva l'editing di una riga
onRowEditCancel(data, index)Annulla l'editing di una riga
getEditingRows()Restituisce le righe attualmente in editing
saveState()Salva lo stato corrente nello storage configurato
restoreState()Ripristina lo stato dallo storage
clearState()Cancella lo stato salvato
createState()Crea uno snapshot dello stato senza salvarlo

Accessibilità

La tabella usa markup semantico <table>, <thead>, <th>, <td>. Le colonne ordinabili ricevono l'attributo aria-sort. Il paginatore interno usa <nav> con aria-label localizzato tramite il sistema i18n.

TypeScript

import type {
  DataTableProps,
  DataTableEmits,
  DataTableFilterMeta,
  DataTableSortMeta,
  DataTablePageEvent,
  DataTableSortEvent,
  DataTableFilterEvent,
  DataTableRowClickEvent,
  DataTableRowSelectEvent,
  DataTableState,
  ColumnProps,
  ColumnSlots,
} from '@pzeta/vue-components'