# Tableau
Tableau de données. Prend en charge le tri (contrôlé / non contrôlé), le filtrage par colonne, le redimensionnement des colonnes par glisser-déposer, les en-têtes multi-niveaux (imbrication illimitée via children) et les colonnes fixes ; définir height active le défilement virtuel (rowHeight doit alors correspondre à la hauteur réelle des lignes).
<template>
<div style="max-width: 760px">
<p class="demo-note">size="small" + maxHeight + tri par défaut (defaultSortProp/defaultSortOrder) + filtre</p>
<LhTable
:data="rows"
:columns="columns"
size="small"
stripe
border
:max-height="200"
row-key="name"
default-sort-prop="dynasty"
default-sort-order="asc"
:default-filtered-values="{ dynasty: ['Song'] }"
>
<template #price="{ value }">
<span style="color: var(--lh-primary-color); font-weight: 600">{{ value }}</span>
</template>
</LhTable>
<p class="demo-note">La colonne « Dynastie » est triée par défaut en ordre croissant et pré-filtrée sur « Song » ; le bouton de filtre de l'en-tête permet de modifier les critères.</p>
<p class="demo-note" style="margin-top: 16px">En-têtes imbriquées (children) + élargissement par resizable + formatter + sorter personnalisé</p>
<LhTable :data="rows2" :columns="groupColumns" border :height="180" :row-height="40" :sorter="dynastySorter">
<template #price="{ value }">
<span style="color: var(--lh-primary-color); font-weight: 600">{{ value }}</span>
</template>
</LhTable>
<p class="demo-note">La colonne « Provenance » est mise en forme par formatter en « Collection impériale / Collection privée » ; la colonne « Estimation » est élargissable (resizable).</p>
</div>
</template>
<script>
export default {
data: () => ({
rows: [
{ name: 'Voyageurs parmi les montagnes et les rivières', dynasty: 'Song', price: 1800 },
{ name: 'Séjour dans les monts Fuchun', dynasty: 'Yuan', price: 2600 },
{ name: 'Mille lieues de fleuves et de montagnes', dynasty: 'Song', price: 3200 },
{ name: 'Le long de la rivière lors de la fête Qingming', dynasty: 'Song', price: 1500 },
{ name: 'Le festin nocturne de Han Xizai', dynasty: 'Cinq dynasties', price: 2100 },
],
rows2: [
{ name: 'Voyageurs parmi les montagnes et les rivières', dynasty: 'Song', provenance: 'impériale', price: 1800 },
{ name: 'Séjour dans les monts Fuchun', dynasty: 'Yuan', provenance: 'impériale', price: 2600 },
{ name: 'Le long de la rivière lors de la fête Qingming', dynasty: 'Song', provenance: 'impériale', price: 1500 },
{ name: 'Blanc lumineux la nuit', dynasty: 'Tang', provenance: 'privée', price: 980 },
],
columns: [
{ prop: 'name', label: 'Œuvre', width: 160 },
{
prop: 'dynasty',
label: 'Dynastie',
width: 120,
sortable: true,
filters: [
{ text: 'Song', value: 'Song' },
{ text: 'Yuan', value: 'Yuan' },
{ text: 'Cinq dynasties', value: 'Cinq dynasties' },
],
},
{ prop: 'price', label: 'Estimation (en dizaines de milliers)', width: 140, align: 'right', slot: 'price' },
],
groupColumns: [
{
label: "Informations sur l'œuvre",
children: [
{ prop: 'name', label: 'Œuvre', width: 150 },
{
prop: 'provenance',
label: 'Provenance',
width: 100,
formatter: (r) => (r.provenance === 'impériale' ? 'Collection impériale' : 'Collection privée'),
},
],
},
{
label: 'Valorisation',
children: [
{ prop: 'dynasty', label: 'Dynastie', width: 90, sortable: true },
{ prop: 'price', label: 'Estimation (en dizaines de milliers)', width: 130, align: 'right', resizable: true, slot: 'price' },
],
},
],
}),
methods: {
dynastySorter(a, b) {
const order = ['Tang', 'Cinq dynasties', 'Song', 'Yuan']
return order.indexOf(String(a.dynasty)) - order.indexOf(String(b.dynasty))
},
},
}
</script>
# Props
| Prop | Description | Type | Valeur par défaut |
|---|---|---|---|
| data | Données des lignes | LhTableRow[] | [] |
| columns | Configuration des colonnes | LhTableColumn[] | [] |
| height | Hauteur du corps du tableau (la définition active le défilement virtuel ; un nombre correspond à des px) | number \| string | — |
| maxHeight | Hauteur maximale en mode non virtuel | number \| string | — |
| rowHeight | Hauteur des lignes pour le défilement virtuel (doit correspondre à la hauteur réelle) | number | — |
| stripe / border | Rayures zébrées / bordures des cellules | boolean | false |
| size | Taille | 'small' \| 'default' \| 'large' | 'default' |
| rowKey | Nom du champ servant de clé de ligne | string | — |
| defaultSortProp / defaultSortOrder | Colonne / direction du tri par défaut | string / LhTableSortOrder | — |
| sorter | Fonction de tri personnalisée | (a, b) => number | — |
| resizable | Active le redimensionnement des colonnes (nécessite également la configuration resizable au niveau de la colonne, qui doit avoir une width numérique) | boolean | false |
| defaultFilteredValues | État de filtrage par défaut (non contrôlé, clé = prop de la colonne) | Record<string, (string \| number)[]> | — |
| filteredValues | État de filtrage contrôlé (:filtered-values.sync) | Record<string, (string \| number)[]> | — |
| sx | Propriétés de mise en page rapide | — | — |
# Events
sortChange ({ prop, order }), filterChange ({ prop, values }), columnResize ({ prop, width }), update:filteredValues, rowClick (row, index)
# Slots
| Slot | Description |
|---|---|
<nom de slot de colonne> | Cellule personnalisée, paramètres de portée { row, column, index, value } (la colonne est désignée par column.slot) |
| empty | Contenu en l'absence de données (par défaut : « 暂无数据 ») |
# Accessibilité
La ligne d'en-tête est role="row" avec aria-sort sur les colonnes triables, les lignes du corps sont role="row" ;
le panneau de filtre est role="menu", la poignée de redimensionnement porte un aria-label et un tabindex, et permet un ajustement au clavier vers la gauche / la droite.
Copyright © 2024-2026 FengMo WenXue