Documentation/Vue d'ensemble
Tableau de données
Un tableau Nuxt UI de 2 000 tâches, virtualisé et avec recherche, trié en faisant glisser ses lignes par leurs poignées.
Cette page a été traduite par IA et peut contenir des inexactitudes. Lire l'original en anglais
Chargement de la démo…
<script setup lang="ts">
import { DnDProvider } from '@vue-dnd-kit/core';
import TaskTable from './TaskTable.vue';
</script>
<template>
<!-- The row in hand: a table row can't have a shadow, so its overlay content has it. -->
<DnDProvider overlay-class="overflow-hidden rounded-md bg-default shadow-xl ring ring-accented">
<TaskTable />
</DnDProvider>
</template>Le UTable de Nuxt UI rend le tableau, ses lignes et son virtualiseur : seules les lignes à l'écran
sont dans le DOM. Vue DnD Kit les trie. Le tableau est celui de la bibliothèque tel quel, avec ses
slots et ses classes ui ; rien n'en est réécrit.
Ce qu'il faut regarder
TaskTable.vue: la liste triable est le<tbody>du tableau, trouvé grâce autableRefqu'exposeUTable. Le tableau reçoit le brouillon de la liste commedata, si bien que les lignes bougent pendant que vous faites glisser, etget-row-idleur donne la tâche pour clé, comme le fait la liste.axis: 'y'garde le glissement dans sa colonne, etrestrictToFirstScrollableAncestorà l'intérieur du tableau : son conteneur défilable est le premier élément défilable autour des lignes. Agrandissez la démo : le tableau remplit l'écran.RowGrip.vue:UTablerend les lignes, donc aucun de vos composants n'est une ligne. La poignée de la première cellule (le slot#grip-cell) fait de la ligne qui l'entoure l'item, et en est la poignée (handle).- La recherche est le
filterde la liste : le tableau affiche les tâches qui correspondent, et un dépôt réécrit tout le tableau des tâches, les tâches masquées là où elles étaient. tasks.ts: 2 000 tâches dans unshallowRef: la bibliothèque ne regarde jamais à l'intérieur.
Une ligne que le tableau rend
La poignée appelle makeSortableItem avec un getter pour la ligne : le <tr> qui l'entoure, une
fois rendu. En tant que handle, la poignée reçoit le focus et les attributs ARIA, et le reste de la
ligne reste libre pour les clics et la sélection de texte.
const grip = useTemplateRef<HTMLElement>('grip');
makeSortableItem(() => grip.value?.closest('tr') ?? null, {
id: () => props.task.id,
handle: grip,
label: () => props.task.title,
});
<UTable ref="table" :data="items" :get-row-id="(task: Task) => task.id" …>
<template #grip-cell="{ row }">
<RowGrip :task="row.original" />
</template>
</UTable>
L'overlay est la copie de la ligne faite par la bibliothèque, dans un tableau à elle avec les
largeurs des cellules. Une ligne de tableau ne dessine pas d'ombre, donc l'overlay-class du
provider en donne une au contenu de l'overlay, avec le fond du tableau et un anneau. Les classes
ui de la ligne teintent son emplacement pendant qu'elle voyage
(data-[dnd-placeholder]:bg-primary/5).
<DnDProvider overlay-class="overflow-hidden rounded-md bg-default shadow-xl ring ring-accented">
<TaskTable />
</DnDProvider>
Lignes virtualisées
virtualize donne au tableau TanStack Virtual : les lignes à l'écran et 8 de plus autour d'elles
(overscan) sont rendues, entre deux lignes d'espacement.
<UTable
:data="items"
:watch-options="{ deep: false }"
:virtualize="{ estimateSize: 45, overscan: 8, onChange: () => captureLayout() }"
class="min-h-0 flex-1"
/>
estimateSizeest une première estimation : le virtualiseur mesure chaque ligne quand il la rend. Une mesure déplace les lignes en dessous, etonChangeappelle lecaptureLayout()de la liste, si bien que la bibliothèque anime ce déplacement pendant un glissement au lieu de le laisser sauter.- Le tableau est le conteneur défilable, et la ligne en main reste à l'intérieur : près de son bord haut ou bas, un glissement le fait défiler, et de nouvelles lignes sont rendues à mesure qu'elles apparaissent.
- Le brouillon est un nouveau tableau après chaque déplacement, donc
UTablen'a pas besoin d'en observer le contenu (deep: false). - Faites défiler loin de la ligne que vous tenez : elle sort de la plage rendue et est démontée. Le
glissement continue : l'overlay l'affiche toujours, et elle atterrit là où le brouillon la place.
Une liste virtuelle à vous peut la garder montée avec
rangeExtractor(voir Listes virtuelles). Un tableau dispose ses lignes entre des lignes d'espacement, où une ligne rendue loin des autres les écarterait, donc celui-ci la laisse partir.
Chercher, puis faire glisser
const { items, captureLayout } = makeSortableList(() => table.value?.tableRef?.tBodies[0] ?? null, {
items: tasks,
filter: (task) => {
const text = query.value.trim().toLowerCase();
return !text || `${task.id} ${task.title} ${task.assignee}`.toLowerCase().includes(text);
},
axis: 'y',
modifiers: [restrictToFirstScrollableAncestor],
label: 'Tasks',
});
Cherchez « Mia », déplacez l'une de ses tâches au-dessus d'une autre, puis videz la recherche : ses
tâches sont dans le nouvel ordre, et toutes les autres tâches sont là où elles étaient. Le
e.to.index du dépôt compte les lignes affichées ; e.result contient tout le tableau des tâches.
- La ligne. Un slot qui rend la ligne entière (
#itemde Vuetify,#bodyde Quasar) vous donne son élément : faites-en l'item. Là où vous n'obtenez que des cellules (le#bodyd'uneColumnPrimeVue, le slot par défaut d'une colonne Element Plus, lerenderde Naive UI), placez une poignée dans l'une d'elles et faites de sonclosest('tr')l'item, comme ici. - La liste. Le
<tbody>dans l'élément racine du tableau : une ref de template sur le tableau vous donne le composant, et son$ell'élément. - Les clés et les données. Donnez aux lignes votre id pour clé (
item-value,row-key,dataKey) et passez au tableau le brouillon de la liste comme données. - Son propre tri désactivé. Laissez de côté le réordonnancement des lignes propre au tableau et son tri par colonne : l'ordre est celui de la liste.
- Les tableaux virtuels placent leurs lignes entre des espaceurs ou dans des boîtes absolues : les deux fonctionnent, et un glissement survit au démontage de sa ligne.
@nuxt/ui/vite, Tailwind CSS et UApp autour de
l'exemple. Dans une application Nuxt avec le module @nuxt/ui, copiez le dossier et rendez
index.vue dans une page.Clavier et lecteurs d'écran
Atteignez la poignée d'une tâche avec Tab et appuyez sur Space pour saisir la ligne.
ArrowUp et ArrowDown la déplacent, Space la dépose,
Escape la remet à sa place. Les lignes ont un label, et la liste aussi : les
lecteurs d'écran entendent « Fix the login form dropped at position 3 of 2000 in Tasks. », pas des
clés.
En savoir plus : Listes virtuelles · N'afficher qu'une partie des items · Style : Tailwind et kits d'UI · Accessibilité