Skip to content

DataTable

Visão geral

O LxDataTable é uma tabela de dados construída sobre o DataTable do PrimeVue, adaptada ao design system da Linx. Oferece scroll horizontal com setas de navegação, cabeçalhos fixos, ordenação, linhas listradas, seleção de linhas, reordenação drag-and-drop e integração com o LxDataTablePaginator.

Utiliza o LxDataTableColumn para definição de colunas — um wrapper direto do Column do PrimeVue, que aceita todas as suas propriedades.

Clique para visualizar o código
vue
<script setup>
import { ref, computed, shallowRef } from 'vue';
import { LxDataTable, LxDataTableColumn, LxDataTablePaginator } from '@lde/lxcomponents';

const produtos = shallowRef([
	{ id: 1, nome: 'Notebook Pro 15', categoria: 'Eletrônicos', preco: 4599.9, estoque: 12, status: 'Ativo' },
	{ id: 2, nome: 'Mouse Gamer RGB', categoria: 'Periféricos', preco: 189.9, estoque: 45, status: 'Ativo' },
	{ id: 3, nome: 'Teclado Mecânico', categoria: 'Periféricos', preco: 320.0, estoque: 0, status: 'Inativo' },
	{ id: 4, nome: 'Monitor 27" 4K', categoria: 'Eletrônicos', preco: 2799.0, estoque: 8, status: 'Ativo' },
	{ id: 5, nome: 'Webcam Full HD', categoria: 'Periféricos', preco: 249.0, estoque: 30, status: 'Ativo' },
	{ id: 6, nome: 'Headset Bluetooth', categoria: 'Áudio', preco: 399.9, estoque: 0, status: 'Inativo' },
	{ id: 7, nome: 'SSD 1TB NVMe', categoria: 'Armazenamento', preco: 489.0, estoque: 22, status: 'Ativo' },
	{ id: 8, nome: 'Fonte 750W 80+', categoria: 'Componentes', preco: 520.0, estoque: 14, status: 'Ativo' },
	{ id: 9, nome: 'Placa de Vídeo RTX', categoria: 'Componentes', preco: 3200.0, estoque: 3, status: 'Ativo' },
	{ id: 10, nome: 'Processador i9', categoria: 'Componentes', preco: 2100.0, estoque: 6, status: 'Ativo' },
	{ id: 11, nome: 'Memória RAM 32GB', categoria: 'Componentes', preco: 610.0, estoque: 18, status: 'Ativo' },
	{ id: 12, nome: 'Hub USB-C 7-in-1', categoria: 'Periféricos', preco: 159.9, estoque: 55, status: 'Ativo' }
]);

const currentPage = ref(1);
const itemsPerPage = ref(5);

const dadosPaginados = computed(() => {
	const inicio = (currentPage.value - 1) * itemsPerPage.value;
	return produtos.value.slice(inicio, inicio + itemsPerPage.value);
});

const handlePaginacao = ({ currentPage: pagina, itemsPerPage: porPagina }) => {
	currentPage.value = pagina;
	itemsPerPage.value = porPagina;
};

const formatPreco = (valor) => valor.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' });

const statusClass = (status) => (status === 'Ativo' ? 'badge bg-success' : 'badge bg-secondary');
</script>

<template>
	<LxDataTable :value="dadosPaginados" data-key="id" :scroll-config="{ height: 'flex' }">
		<LxDataTableColumn field="id" header="ID" header-style="width: 60px" />
		<LxDataTableColumn field="nome" header="Produto" :sortable="true" />
		<LxDataTableColumn field="categoria" header="Categoria" :sortable="true" />
		<LxDataTableColumn field="estoque" header="Estoque" header-style="width: 100px; text-align: center" body-style="text-align: center">
			<template #body="{ data }">
				<span :style="{ color: data.estoque === 0 ? 'var(--lx-danger)' : 'inherit' }">
					{{ data.estoque }}
				</span>
			</template>
		</LxDataTableColumn>
		<LxDataTableColumn field="preco" header="Preço" :sortable="true" header-style="text-align: right; width: 130px" body-style="text-align: right">
			<template #body="{ data }">
				{{ formatPreco(data.preco) }}
			</template>
		</LxDataTableColumn>
		<LxDataTableColumn field="status" header="Status" header-style="text-align: center; width: 100px" body-style="text-align: center">
			<template #body="{ data }">
				<span :class="statusClass(data.status)">{{ data.status }}</span>
			</template>
		</LxDataTableColumn>

		<template #paginator>
			<LxDataTablePaginator
				:total-items="produtos.length"
				:current-page="currentPage"
				:items-per-page="itemsPerPage"
				:page-options="[5, 10]"
				@update:pagination="handlePaginacao"
			/>
		</template>
	</LxDataTable>
</template>

Formato do v-model

ℹ️ O LxDataTable usa v-model:selection (não v-model). Armazena as chaves das linhas selecionadas em um Set.

Inicialização: new Set() — nunca null nem [].

javascript
const selecao = ref(new Set())
// após selecionar linhas com Id 3 e 7:
// selecao.value === Set { 3, 7 }
vue
<LxDataTable
  :value="dados"
  v-model:selection="selecao"
  :selection-config="{ dataKey: 'Id', selectionMode: 'multiple' }"
>
  <LxDataTableColumn field="Nome" header="Nome" />
</LxDataTable>

Para enviar ao backend:

javascript
const idsSelecionados = [...selecao.value]  // [3, 7]

Componentes

O LxDataTable é composto por três componentes principais:

ComponenteDescrição
LxDataTableContêiner principal da tabela
LxDataTableColumnDefine cada coluna (wrapper de Column do PrimeVue — aceita todas as suas props)
LxDataTableStyleSelectorControle de alternância entre tamanho compacto e confortável

Consulte a documentação dedicada dos componentes auxiliares quando precisar controlar a visualização ou a paginação externamente:

Propriedades

NomeDescriçãoTipoPadrão
idID raiz da tabelaString'lx-datatable'
loadingExibe o skeleton de carregamentoBooleanfalse
navigationConfigConfiguração das setas de navegação horizontal. Ver NavigationConfigObject{}
scrollConfigConfiguração de scroll. Ver ScrollConfigObject{}
visualizationConfigConfiguração visual (tamanho, classes, listras). Ver VisualizationConfigObject{}
paginationConfigConfiguração do paginador nativo do PrimeVue. Ver PaginationConfigObject{}
reorderConfigConfiguração de reordenação drag-and-drop. Ver ReorderConfigObject{}
selectionConfigHabilita e configura a seleção de linhas. Ver SelectionConfigObject | nullnull
selectionConjunto de chaves selecionadas (suporta v-model:selection)Set | Arraynew Set()
NomeDescriçãoTipoPadrão
showExibe as setas de navegação horizontalBooleantrue
scrollWidthLargura da scrollbar customizadaString'4.75px'
btnSizeTamanho dos botões de navegaçãoString'3rem'

ScrollConfig

NomeDescriçãoTipoPadrão
scrollableHabilita o scroll na tabelaBooleantrue
heightAltura da área de scroll ('flex' para preencher container)String'flex'
classClasse CSS do contêiner de scrollString'gray-scroll'
virtualScrollerOptionsConfiguração de virtual scroll do PrimeVueObject | nullnull

VisualizationConfig

NomeDescriçãoTipoPadrão
stripedRowsExibe linhas alternadas (zebra)Booleantrue
containerClassClasse CSS do contêiner externoString'lx-datatable-container'
tableClassClasse CSS da tag <table>String'table table-hover'
tableRootClassClasse CSS adicional no elemento raiz do DataTableStringundefined
noWrapHeaderImpede quebra de linha nos cabeçalhosBooleantrue
ptPassthroughPassthrough do PrimeVue para personalização avançadaObject{}
useGridLoadingUsa LxGridLoading no estado de carregamentoBooleantrue
sizeDensidade da tabela ('small' ou 'large')'small' | 'large'undefined

PaginationConfig

Configuração do paginador nativo do PrimeVue. Quando o slot #paginator é utilizado, o LxDataTable desabilita automaticamente o paginador nativo para evitar duplicidade de controles.

É recomendado utilizar o componente LxDataTablePaginator (dentro ou fora do slot #paginator) para ter controle de paginação via API.

NomeDescriçãoTipoPadrão
paginatorHabilita o paginador nativo do PrimeVueBooleanfalse
rowsNúmero de linhas por páginaNumber10
rowsPerPageOptionsOpções de linhas por páginaNumber[][10, 25, 50, 100]
paginatorTemplateTemplate de controles do paginadorString'RowsPerPageDropdown ...'
currentPageReportTemplateFormato do relatório de página atualString'{first} - {last} de {totalRecords}'

ReorderConfig

NomeDescriçãoTipoPadrão
showGhostExibe o ghost de arrastarBooleantrue
hideNativeGhostOculta o ghost nativo do browserBooleantrue
rowGhostHeaderTextTexto do ghost ao mover linhaString'Movendo linha'
columnGhostHeaderTextTexto do ghost ao mover colunaString'Movendo coluna'
rowGhostIconClassÍcone do ghost de linhaString'fas fa-arrows-alt'
columnGhostIconClassÍcone do ghost de colunaString'fas fa-grip-vertical'
getRowGhostValuesFunção que retorna os valores exibidos no ghost de linhaFunction | nullnull
getColumnGhostValuesFunção que retorna os valores exibidos no ghost de colunaFunction | nullnull

SelectionConfig

NomeDescriçãoTipoPadrão
activeAtiva a seleção de linhas com checkboxesBooleantrue
columnWidthLargura da coluna de seleçãoString'3rem'
frozenCongela a coluna de seleção horizontalmenteBooleanfalse

Eventos

NomeDescriçãoPayload
update:selectionEmitido quando a seleção de linhas muda (suporta v-model:selection)Set | Array
row-reorderEmitido ao finalizar reordenação de linhaEvent do PrimeVue
column-reorderEmitido ao finalizar reordenação de colunaEvent do PrimeVue

Slots

NomeDescrição
defaultColunas da tabela (LxDataTableColumn)
paginatorSlot para o LxDataTablePaginator ou qualquer paginador customizado, renderizado após a tabela
emptySubstitui o estado vazio padrão
ghost-previewConteúdo customizado do ghost de reordenação. Expõe os valores via scoped slot

Os demais slots do DataTable do PrimeVue (header, footer, groupheader, entre outros) são repassados automaticamente ao componente base.

Métodos (via ref)

NomeDescrição
resetTable()Força re-renderização da tabela (útil ao alterar colunas dinamicamente)
getSelectedKeys()Retorna as chaves das linhas selecionadas
cleanSelectedKeys()Limpa a seleção atual

Uso com LxDataTablePaginator

Use o LxDataTablePaginator via slot #paginator. Nesse modo, o paginador nativo do PrimeVue é desabilitado automaticamente:

vue
<LxDataTable
  :value="dadosPaginados"
  data-key="id"
>
  <LxDataTableColumn field="nome" header="Nome" />

  <template #paginator>
    <LxDataTablePaginator
      :total-items="totalItems"
      :current-page="currentPage"
      @update:pagination="handlePaginacao"
    />
  </template>
</LxDataTable>

Ou posicione o LxDataTablePaginator fora da tabela, com total controle de layout. Nesse caso, como o slot não está sendo usado, mantenha paginationConfig.paginator: false caso queira garantir que o paginador nativo continue oculto:

vue
<LxDataTable :value="dadosPaginados" :pagination-config="{ paginator: false }">
  <LxDataTableColumn field="nome" header="Nome" />
</LxDataTable>

<LxDataTablePaginator
  :total-items="totalItems"
  :current-page="currentPage"
  @update:pagination="handlePaginacao"
/>

Para alternar a densidade visual da tabela entre os modos compacto e confortável, utilize o LxDataTableStyleSelector em conjunto com a propriedade visualizationConfig.size:

vue
<script setup>
import { computed, ref } from 'vue';
import { LxDataTable, LxDataTableColumn, LxDataTableStyleSelector, TableStyle } from '@lde/lxcomponents';

const styleId = ref(TableStyle.COMPACT.id);

const visualizationConfig = computed(() => ({
  size: styleId.value
}));
</script>

<template>
  <LxDataTableStyleSelector v-model="styleId" />

  <LxDataTable :value="dados" :visualization-config="visualizationConfig">
    <LxDataTableColumn field="nome" header="Nome" />
  </LxDataTable>
</template>

O uso detalhado do selector está em LxDataTableStyleSelector.

Desenvolvido pelo time Linx Microvix