Dokumentation/Leitfäden
DevTools
Ein Vue-DnD-Kit-Tab in den Vue DevTools und den Nuxt DevTools – eine Live-Minikarte, ein Joystick, der wirklich zieht, Optionen live bearbeiten und ein Log jedes Drags.
Diese Seite wurde von KI übersetzt und kann Ungenauigkeiten enthalten. Englisches Original lesen
@vue-dnd-kit/devtools fügt den Vue DevTools (vite-plugin-vue-devtools) und den Nuxt DevTools
einen Tab Vue DnD Kit hinzu. Er zeigt jede Liste, jeden Baum und jedes Drop-Ziel der Seite auf
einer Live-Minikarte, zieht jedes Element mit einem Joystick, bearbeitet Optionen, während die App
läuft, und protokolliert, was jeder Drag getan hat. Er funktioniert nur in der Entwicklung: Nichts
davon gelangt in einen Produktions-Build.
Der Tab ist eine eigene Seite, die dein Dev-Server neben deiner App ausliefert, deshalb kann er nicht in dieser Dokumentation laufen. Drei Schritte richten ihn ein.
Installation
1. Die Pakete hinzufügen
npm i -D @vue-dnd-kit/devtools @vue-dnd-kit/actions
@vue-dnd-kit/actions ist eine Peer-Dependency: Die Bewegungen des Tabs laufen darüber. npm 7+
und pnpm installieren es von selbst; mit Yarn 1 füge es hinzu.
2. Das Plugin hinzufügen
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
import vueDevTools from 'vite-plugin-vue-devtools';
import { vueDnDKitDevtools } from '@vue-dnd-kit/devtools/vite';
export default defineConfig({
// Next to the Vue DevTools plugin: the tab joins its sidebar.
plugins: [vueDevTools(), vueDnDKitDevtools(), vue()],
});
export default defineNuxtConfig({
// With @vue-dnd-kit/devtools installed, the tab appears in development.
modules: ['@vue-dnd-kit/nuxt'],
});
Mit Vite tut das Plugin auf dem Dev-Server (vite serve) drei Dinge: Es liefert den Tab unter
/__vue-dnd-kit-devtools/ aus (unterhalb deiner base), fügt ihn den Vue DevTools hinzu und
sorgt dafür, dass die Seite ihm berichtet, bevor deine App startet. Kein app.use() nötig, und
Builds bleiben unberührt.
Mit Nuxt findet das Modul @vue-dnd-kit/nuxt das Paket, liefert den Tab aus, fügt ihn den Nuxt
DevTools hinzu und installiert den Teil auf der Seite mit einem Client-Plugin.
vueDndKit: { devtools: false } schaltet das ab.
3. Die App in der Entwicklung starten
Starte den Dev-Server wie gewohnt (vite, nuxt dev) und öffne die App: Der Tab ist bereit. Jeder
Provider der Seite erscheint darin, egal in welcher App er rendert.
Ohne die Plugins
Für einen eigenen Dev-Server oder eine Seite, die Vite nicht aus einer index.html ausliefert
(SSR-Setups), installiere den Teil auf der Seite selbst:
import { createApp } from 'vue';
import { DnDDevtools } from '@vue-dnd-kit/devtools';
import App from './App.vue';
const app = createApp(App);
app.use(DnDDevtools); // before mount: providers set up earlier aren't seen
app.mount('#app');
Oder importiere @vue-dnd-kit/devtools/auto als Erstes in der Einstiegsdatei. Nimm
vueDnDKitDevtools({ inject: false }), wenn das Plugin den Tab ausliefern soll, du den Teil auf der
Seite aber selbst installierst; serveTab() aus @vue-dnd-kit/devtools/vite ist die Middleware,
die den Tab ausliefert.
app.use(DnDDevtools) und der auto-Import auf fast
nichts: Jeder Einstiegspunkt prüft zuerst process.env.NODE_ENV, und Bundler werfen den Rest weg.
Auf dem Server tun sie nichts.Öffnen
- Vue DevTools: Alt + Shift + D oder der Vue-Button unten auf der Seite, dann der Tab Vue DnD Kit.
- Nuxt DevTools: Alt + Shift + D oder der Nuxt-Button, dann Vue DnD Kit (in der Seitenleiste oder ihrem Überlaufmenü).
- Ein eigenes Fenster: Öffne
http://localhost:5173/__vue-dnd-kit-devtools/auf deinem Dev-Server oder nutze den ⧉-Button des Tabs. Praktisch auf einem zweiten Bildschirm. Sind mehrere Seiten offen, wählt ein Select oben die, die beobachtet wird.
Der Tab im Überblick
| Teil | Was er enthält |
|---|---|
| Obere Leiste | Was der Drag gerade tut (dragging card-3 → done (accepts)), die beobachtete Seite, ⌖ Pick, die Anzahl bearbeiteter Optionen mit einem Reset, ⧉ (ein eigenes Fenster) und das Theme. |
| Links: die Registry | Jeder Provider als Baum: seine Listen, Bäume, Drop-Ziele und ziehbaren Elemente. ☰ blendet sie ein oder aus. |
| Mitte: Map und Log | Die Live-Minikarte der Seite oder das Log der Drags. |
| Rechts: Drive, Options, State | Der Joystick und die Buttons zum Verschieben, die Optionen des gewählten Knotens und was der Provider darüber weiß. |
Wähle einen Knoten in der Registry oder ein Element auf der Karte, und die rechte Seite folgt ihm.
Die Minikarte
Eine Live-Karte pro Liste, Baum und Drop-Ziel, mit Kopien ihrer Elemente dort, wo sie sind – dieselben Klone, die das Overlay zeigen würde, mit dem CSS der Seite. Während eines Drags markiert sie:
- die Listen und Ziele, die den Drag annehmen (blau) oder ablehnen (rot);
- den Platzhalter und das Ziel unter dem Zeiger;
- den Zeiger, die Box des Overlays und die Einfügelinie von Listen mit
placeholder: 'indicator'.
Ein Klick wählt ein Element und hebt es auf der Seite hervor; ein Doppelklick scrollt die Seite dorthin. Nutze die Karte, wenn ein Drop nicht dort landet, wo du es erwartest: Sie zeigt auf einen Blick, welche Listen den Drag annehmen.
Drive: der Joystick
Wähle ein Element – auf der Karte, in der Registry oder mit ⌖ Pick, das das nächste Drücken auf ein ziehbares Element der Seite abfängt, statt es wirken zu lassen – und drück den Knauf des Joysticks. Das Element wird aufgenommen und bewegt sich in diese Richtung, umso schneller, je weiter der Knauf von der Mitte entfernt ist. Lass los, und es hält an; Drop und Cancel beenden den Drag.
Es ist ein echter Drag per Zeiger von einem Sensor namens devtools, gebaut mit der öffentlichen
Sensor-API: Listen sortieren sich darunter, Container
scrollen an ihren Rändern, und onBeforeDrop und onDrop laufen wie bei jedem Drag. Deaktivierte
Elemente werden nicht aufgenommen. Auch ein Drag per Tastatur, den die Seite gestartet hat, lässt
sich steuern.
Elemente sortierbarer Listen bekommen zusätzlich Buttons: nach oben, nach unten, an den Anfang, ans
Ende, in eine andere Liste der Gruppe. Jeder ist ein Drag per Tastatur mit
moveItem. Unter dem Joystick eine große Kopie dessen,
was das Overlay zeigt.
| Taste im Tab | Wirkung |
|---|---|
| Pfeiltasten oder W A S D | Den Knauf in diese Richtung drücken, halb; mit Shift ganz |
| G | Das gewählte Element aufnehmen |
| Space / Enter | Ablegen |
| Escape | Abbrechen |
| P | Auf der Seite auswählen |
Options
Jede Option, die kein Callback ist, lässt sich bearbeiten, während die App läuft. Wähle den Knoten und öffne Options:
| Knoten | Optionen |
|---|---|
| Provider | overlayFit, autoScroll, collision, modifiers (die der Bibliothek, nach Namen), animation, dropAnimation, animateChanges, activation, keyboard, haptics, copyModifier … |
| Liste | disabled, strategy, placeholder, behavior, multiple, sort, dropOutside, acceptMode, animation, animateChanges, autoScroll, modifiers |
| Baum | placeholder, indentation, nesting, maxDepth … |
| Drop-Ziel | disabled, priority, accept, acceptMode |
| Element | disabled, keyboardMode, activation |
Eine Änderung gilt sofort, nur für diese Seite, und wird nie in deinen Code geschrieben: Die Bibliothek liest den neuen Wert dort, wo sie die Option liest. Sie gilt, bis du sie zurücksetzt (↺ pro Option oder der Reset in der oberen Leiste), der Provider unmountet oder die Seite neu lädt. Neben einer bearbeiteten Option steht der Wert aus deinem Code. Elemente, die gemountet werden, während eine Änderung gesetzt ist – Zeilen einer virtuellen Liste –, bekommen sie auch.
State
Was jeder Provider über den gewählten Knoten weiß:
- die Drag-Sitzung: Status, die aktiven IDs, Elemente und der Sensor, das Ziel und ob es annimmt, der Zeiger, das Overlay, die Sitzung der sortierbaren Gruppe und die Einfügelinie;
- eine Liste: ihre Reihenfolge und ihr Entwurf; ein Baum: seine Zeilen;
- ein Element: sein Typ, seine Daten und seine Position; ein Drop-Ziel: seine Regeln.
Elemente mounten und unmounten ohne Events: Die Registry holt das innerhalb einer Sekunde auf.
Log
Ein Band pro Drag, der Reihe nach:
| Eintrag | Was er sagt |
|---|---|
drag start | Die IDs, der Sensor und ob per Touch, die Liste, aus der er kommt. |
over, left | Jedes Ziel, das betreten und verlassen wurde, und ob es annimmt. |
release | Das Ziel, über dem losgelassen wurde, während onBeforeDrop entscheidet. |
onBeforeDrop | Das Urteil: angenommen, teilweise angenommen, von einem Hook abgelehnt, vom accept des Ziels abgelehnt, und wie lange die Hooks gebraucht haben. |
drop | Das Ziel; bei sortierbaren Listen die Bewegung, e.result und ob preventDefault() aufgerufen wurde. |
cancel | Warum: abgebrochen (Escape, cancel()), von einem Hook abgelehnt oder vom accept des Ziels abgelehnt. |
Außerdem auto-scroll on und off, die announcement-Texte (standardmäßig ausgeblendet) und,
außerhalb von Drags, animate (Änderungen an den Elementen einer Liste, die kein Drag gemacht
hat). Klick auf einen Eintrag, um seine Daten zu sehen. Ein Tab, der später geöffnet wird, bekommt
die bisherigen Drags.
Einen Drop Schritt für Schritt debuggen
Eine Karte will nicht in eine Spalte. Mit offenem Tab:
- Reproduziere es von Hand oder mit Drive, damit deine Hände für den Tab frei bleiben.
- Beobachte die Karte, während die Karte über der Spalte ist. Rot heißt, die Liste lehnt die
Karte ab: Sieh dir ihre
group(put) oder dasacceptdes Ziels an. Blau heißt, sie nimmt an, und das Problem kommt später. - Lies das Log dieses Drags.
onBeforeDropsagt, wer Nein gesagt hat – ein Hook oder dasacceptdes Ziels. Ging der Drop durch, aber deine Daten haben sich nicht geändert, sagt der Eintragdrop, obpreventDefault()aufgerufen wurde und was ine.resultstand: Eine kontrollierte Liste muss es selbst anwenden. - Probier einen Fix live in Options aus – ein lockereres
acceptMode, eine anderecollision,placeholder: 'indicator'– und schreib dann den, der funktioniert, in deinen Code.
Wie es funktioniert
Provider berichten an einen Hook, den der Teil auf der Seite installiert. Bis ein Tab die Seite
beobachtet, werden sie nur erfasst; dann hört die Seite zu wie jeder Monitor und schickt dem Tab,
was er zeigt – alle 40 ms während eines Drags, sonst zweimal pro Sekunde – und hört auf, sobald
einige Sekunden lang kein Tab mehr zugesehen hat. Der Tab spricht mit der Seite über einen
BroadcastChannel des Origins der Seite. Er ändert nichts außer dem, worum du bittest: die Drags,
die Auswahl und die überschriebenen Optionen.