Detaillierte Erklärung zur Verwendung von Vue Smooth DnD, einer verschiebbaren Komponente von Vue

Detaillierte Erklärung zur Verwendung von Vue Smooth DnD, einer verschiebbaren Komponente von Vue

Einführung und Demo

In letzter Zeit besteht Bedarf an einer Drag-and-Drop-Liste und ich habe eine einfache und benutzerfreundliche ziehbare Vue-Komponente gefunden. Amway

Vue Smooth DnD ist eine schnelle, leichtgewichtige Drag-and-Drop- und sortierbare Vue.js-Bibliothek, die die Smooth-DND-Bibliothek umschließt.

Vue Smooth DnD besteht hauptsächlich aus zwei Komponenten, Container und Draggable . Container enthält ziehbare Elemente oder Komponenten und jedes seiner untergeordneten Elemente sollte von Draggable umschlossen sein. Jedes Element, das gezogen werden soll, muss von Draggable umschlossen werden.

Installation: npm i vue-smooth-dnd

Eine einfache Demo, die die grundlegende Verwendung der Komponente zeigt und eine verschiebbare Liste implementiert.

<Vorlage>
    <div>
        <div Klasse="einfache-Seite">
            <Behälter @drop="onDrop">
                <Ziehbar v-for="Artikel in Artikeln" :key="artikel.id">
                    <div Klasse="ziehbares Element">
                        {{item.data}}
                    </div>
                </Ziehbar>
            </Container>
        </div>
    </div>
</Vorlage>

<Skript>
    importiere { Container, ziehbar } aus „vue-smooth-dnd“;

    const applyDrag = (arr, dragResult) => {
        const { entfernterIndex, hinzugefügterIndex, Nutzlast } = dragResult
        console.log(entfernterIndex, hinzugefügterIndex, Nutzlast)
        wenn (entfernterIndex === null und hinzugefügterIndex === null) return arr

        const Ergebnis = [...arr]
        let itemToAdd = Nutzlast

        wenn (entfernterIndex !== null) {
            ZuHinzufügendes Element = Ergebnis.splice(entfernterIndex, 1)[0]
        }

        wenn (addedIndex !== null) {
            Ergebnis.splice(hinzugefügterIndex, 0, hinzuzufügendes Element)
        }

        Ergebnis zurückgeben
    }

    const generateItems = (Anzahl, Ersteller) => {
        const Ergebnis = []
        für (sei i = 0; i < Anzahl; i++) {
            Ergebnis.push(Ersteller(i))
        }
        Ergebnis zurückgeben
    }

    Standard exportieren {
        Name: "Einfach",
        Komponenten: { Container, Draggable },
        Daten() {
            zurückkehren {
                Elemente: generateItems(50, i => ({ id: i, data: "Draggable " + i }))
            };
        },
        Methoden: {
            beim Ablegen(dropResult) {
                diese.items = applyDrag(diese.items, dropResult);
            }
        }
    };

</Skript>

<Stil>
    .ziehbares Element {
        Höhe: 50px;
        Zeilenhöhe: 50px;
        Textausrichtung: zentriert;
        Anzeige: Block;
        Hintergrundfarbe: #fff;
        Umriss: 0;
        Rand: 1px durchgezogen rgba(0, 0, 0, .125);
        Rand unten: 2px;
        Rand oben: 2px;
        Cursor: Standard;
        Benutzerauswahl: keine;
    }
</Stil>

Wirkung

API: Container

Eigentum

Eigentum Typ Standardwert beschreiben
:Orientierung Schnur Vertikale Die Ausrichtung des Containers, die horizontal oder vertikal sein kann
:Verhalten Schnur bewegen Beschreibung Das gezogene Element wird in den Zielcontainer verschoben oder kopiert. Kann verschoben, kopiert, in eine Drop-Zone abgelegt oder enthalten werden. Mit „move“ können Elemente zwischen Containern verschoben werden, mit „copy“ können Elemente in andere Container kopiert werden, die Elemente im Container sind jedoch unveränderlich, mit „drop-zone“ können Elemente zwischen Containern verschoben werden, die Reihenfolge der Elemente im Container ist jedoch festgelegt. contain kann nur innerhalb des Containers verschoben werden.
:Etikett Zeichenfolge, Knotenbeschreibung div Das Element-Tag des Containers, der Standardwert ist div, was eine Zeichenfolge wie tag="table" oder ein Objekt mit Wert- und Props-Attributen sein kann: tag="{value: 'table', props: {class: 'my-table'}}"
:Gruppenname Schnur undefiniert Ziehbare Elemente können zwischen Containern mit demselben Gruppennamen verschoben werden. Wenn der Gruppenname nicht festgelegt ist, akzeptiert der Container keine Elemente von außerhalb. Dieses Verhalten kann durch die Funktion shouldAcceptDrop überschrieben werden. siehe unten.
:Achse sperren Schnur undefiniert Sperrt die Bewegungsachse, die Sie ziehen. Mögliche Werte sind x, y oder undefiniert.
:Ziehgriff-Selektor Schnur undefiniert Wird verwendet, um den CSS-Selektor anzugeben, der Ziehen ermöglicht. Wenn nicht angegeben, kann jede Position innerhalb des Elements erfasst werden.
:Bereichsselektor ohne Ziehen Schnur undefiniert CSS-Selektor zum Deaktivieren des Ziehens hat Vorrang vor dragHandleSelector.
:Ziehen-Beginn-Verzögerung Nummer 0 (200 für Touch-Geräte) Die Einheit ist Millisekunden. Gibt an, wie lange es dauert, auf ein Element zu klicken, bevor mit dem Ziehen begonnen werden kann. Wenn Sie den Cursor vorher mehr als 5 Pixel bewegen, wird der Ziehvorgang abgebrochen.
:Animationsdauer Nummer 250 Die Einheit ist Millisekunden. Gibt die Dauer der Animation zum Platzieren und Neuanordnen von Elementen an.
:Auto-Scroll-aktiviert Boolescher Wert WAHR Wenn sich das gezogene Element dem Rand nähert, wird das erste scrollbare übergeordnete Element automatisch gescrollt. (Ich verstehe dieses Attribut nicht = =)
:Drag-Klasse Schnur undefiniert Klassen, die hinzugefügt werden, während das Element gezogen wird (haben keine Auswirkungen auf die Anzeige des Elements, nachdem der Ziehvorgang beendet ist).
:Drop-Klasse Schnur undefiniert Klassen werden von dem Zeitpunkt an hinzugefügt, an dem das gezogene Element abgelegt wird, bis zu dem Zeitpunkt, an dem es der Seite hinzugefügt wird.
:Entfernen bei Ausfall Boolescher Wert undefiniert Wenn auf „true“ gesetzt und das gezogene Element nicht in einen relevanten Container abgelegt wird, wird onDrop() mit dem Elementindex als „removedIndex“ aufgerufen.
:Platzhalter ablegen Boolescher Wert, Objekt undefiniert Platzhalteroptionen. Enthält className, animationDuration, showOnTop

Demonstration der Effekte von drag-class , drop-class und drop-placeholder.className

<Container #Andere Eigenschaften weglassen...
        :animation-duration="1000" # Animationsverzögerung nach dem Platzieren des Elements drag-class="card-ghost"         
        Drop-Klasse = "Kartengeist-Drop"
        :drop-Platzhalter="{
            className: 'drop-preview', # Platzhalterstil animationDuration: '1000', # Platzhalteranimationsverzögerung showOnTop: true # Gibt an, ob über anderen Elementen angezeigt werden soll. Wenn auf false gesetzt, wird es von anderen Drag-Elementen verdeckt.}"
>
    <!-- Einige verschiebbare Elemente-->
    <Ziehbar>….</Ziehbar>
</Container>

Klasse entsprechender Stil

.Kartengeist {
    Übergang: Transformation 0,18 s einfach;
    transformieren: drehenZ(35 Grad);
    Hintergrund: rot !wichtig;
}
.Karte-Geister-Drop {
    Übergang: Transformiere 1s kubisch-bezier(0,1,43, 0,62,1,56);
    transformieren: drehenZ(0 Grad);
    Hintergrund: grün !wichtig;
}
.drop-vorschau {
    Rand: 1px gestrichelt #abc;
    Rand: 5px;
    Hintergrund: gelb !wichtig;
}

Tatsächlicher Effekt (meine hervorragende Farbabstimmung)

Lebenszyklus

Der Lebenszyklus eines Drags wird durch eine Reihe von Callbacks und Events beschrieben und gesteuert. Das folgende Beispiel enthält zur Veranschaulichung drei Container (das Dokument wird direkt ohne Übersetzung kopiert. Die detaillierte Erklärung der API folgt später.):

Mausaufrufe Callback / Event Parameter Hinweise

nach unten o Erster Klick

verschieben o Anfängliches Ziehen
       |
       | get-child-payload() index Die Funktion sollte die Nutzlast zurückgeben
       |
       | 3 x should-accept-drop() srcOptions, payload Ausgelöst für alle Container
       |
       | 3 x drag-start dragResult wird für alle Container ausgelöst
       |
       | Ziehen-Eingabe
       gegen

verschieben o Über Container ziehen
       |
       | nx drag-leave Wird als verschiebbarer Blättercontainer ausgelöst
       | nx drag-enter Wird ausgelöst, wenn das verschiebbare Objekt den Container betritt
       gegen

nach oben o Fertig ziehen

                 should-animate-drop() srcOptions, payload Wird einmal für gelöschte Container ausgelöst

           3 x drag-end dragResult Ausgelöst für alle Container

           nx drop dropResult Wird nur für Droppable-Container ausgelöst

Beachten Sie, dass should-accept-drop vor jedem drag-start und vor jedem drag-end ausgelöst werden sollte, hier aber der Übersichtlichkeit halber weggelassen wurde.

Das Format des dragResult -Parameters ist:

DragResult: {
    payload, # Die Nutzlast kann als das gezogene Objekt verstanden werden isSource, # Ist es der gezogene Container selbst willAcceptDrop, # Kann es gelöscht werden? }

Das Format des dropResult -Parameters ist:

dropResult: {
    addedIndex, # Der Index des neu hinzugefügten Elements, das platziert werden soll, oder null, wenn es keinen gibt
    removedIndex, # Der Index des zu entfernenden Elements oder null, wenn keiner vorhanden ist
    payload, # Das gezogene Elementobjekt, das durch getChildPayload angegeben werden kann droppedElement, # Das platzierte DOM-Element}

Rückrufe

Rückrufe bieten zusätzliche Logik und Prüfungen vor und während der Benutzerinteraktion.

  • get-child-payload(index) passt payload an onDrop() übergebene Payload-Objekt an.
  • should-accept-drop(sourceContainerOptions, payload) wird verwendet, um zu bestimmen, ob der Container gelöscht werden kann, und überschreibt group-name .
  • should-animate-drop(sourceContainerOptions, payload) gibt false zurück, um eine Drop-Animation zu verhindern.
  • get-ghost-parent() gibt das Element zurück, dem das Ghost-Element (das beim Ziehen angezeigte Element) hinzugefügt werden soll. Der Standardwert ist das übergeordnete Element. In manchen Fällen kann die Positionierung Probleme verursachen. Sie können es anpassen, z. B. durch die Rückgabe document.body .

Ereignis

  • @drag-start Von allen Containern gesendetes Ereignis, wenn mit dem Ziehen begonnen wird. Parameter dragResult .
  • @drag-end Eine Funktion, die von allen Containern aufgerufen wird, wenn das Ziehen endet. Wird vor einem @drop -Ereignis aufgerufen. Parameter dragResult .
  • @drag-enter Ereignis, das vom zugehörigen Container ausgegeben werden soll, wenn das gezogene Element beim Ziehen seine Grenzen überschreitet.
  • @drag-leave Ein Ereignis, das vom zugehörigen Container ausgegeben wird, wenn das gezogene Element beim Ziehen seine Grenzen verlässt.
  • @drop-ready Eine Funktion, die der gezogene Container aufruft, wenn sich der Index einer möglichen Ablageposition im Container ändert. Es wird grundsätzlich jedes Mal aufgerufen, wenn ein ziehbares Objekt im Container verschoben wird, um Platz für das gezogene Element zu schaffen. Parameter dropResult .
  • @drop -Ereignis, das von allen zugehörigen Containern ausgegeben wird, wenn die Platzierung abgeschlossen ist (nachdem die Platzierungsanimation abgeschlossen ist). Der Quellbehälter und alle Behälter, die einen Tropfen aufnehmen können, werden als verbunden betrachtet. Parameter dropResult .

API: Ziehbar

tag

Das gleiche tag wie der Container gibt das DOM-Element-Tag des verschiebbaren Elements an.

Tatsächlicher Kampf

Implementieren Sie einen einfachen Task-Manager für die Teamzusammenarbeit.

<Vorlage>
    <div Klasse="Kartenszene">
        <Behälter
                Ausrichtung="horizontal"
                @drop="onColumnDrop($Ereignis)"
                Ziehgriff-Auswahl = ".column-drag-handle"
        >
            <Ziehbar v-for="Spalte in TaskColumnList" :key="Spaltenname">
                <div Klasse="Kartencontainer">
                    <div Klasse="Kartenspaltenkopfzeile">
                        <span class="column-drag-handle">&#x2630;</span>
                        {{ spaltenname }}
                    </div>
                    <Behälter
                            Gruppenname="Spalte"
                            @drop="(e) => onCardDrop(spalten.id, e)"
                            :get-child-payload="getCardPayload(spalte.id)"
                            Drag-Klasse = "Kartengeist"
                            Drop-Klasse = "Kartengeist-Drop"
                            :drop-placeholder="Platzhalteroptionen ablegen"
                            Klasse = "ziehbarer Container"
                    >
                        <Ziehbares v-for="Aufgabe in Spalte.Liste" :key="Aufgabe.id">
                            <div Klasse="Aufgabenkarte">
                                <div Klasse="Aufgabentitel">{{ Aufgabenname }}</div>
                                <div Klasse = "task-priority" :style = "{ Hintergrund: priorityMap[task.priority].color }">
                                    {{ PrioritätMap[Aufgabe.Priorität].label }}
                                </div>
                            </div>
                        </Ziehbar>
                    </Container>
                </div>
            </Ziehbar>
        </Container>
    </div>
</Vorlage>

<Skript>
    importiere { Container, ziehbar } aus „vue-smooth-dnd“;

    const applyDrag = (arr, dragResult) => {
        const { entfernterIndex, hinzugefügterIndex, Nutzlast } = dragResult
        console.log(entfernterIndex, hinzugefügterIndex, Nutzlast)
        wenn (entfernterIndex === null und hinzugefügterIndex === null) return arr

        const Ergebnis = [...arr]
        let itemToAdd = Nutzlast

        wenn (entfernterIndex !== null) {
            ZuHinzufügendes Element = Ergebnis.splice(entfernterIndex, 1)[0]
        }

        wenn (addedIndex !== null) {
            Ergebnis.splice(hinzugefügterIndex, 0, hinzuzufügendes Element)
        }

        Ergebnis zurückgeben
    }

    const taskList = [
        {
            Name: 'Homepage',
            Priorität: 'P1',
            Status: 'In Entwicklung',
            ID: 1,
        },
        {
            Name: 'Flowchart-Entwicklung',
            Priorität: 'P3',
            Status: „Überprüfung ausstehend“,
            ID: 2,
        },
        {
            Name: 'Statistische Diagrammanzeige',
            Priorität: 'P0',
            Status: 'In Entwicklung',
            ID: 3,
        },
        {
            Name: 'Dateiverwaltung',
            Priorität: 'P1',
            Status: „In Entwicklung“,
            ID: 4,
        }
    ]

    const statusList = ['steht zur Überprüfung an', 'steht zur Entwicklung an', 'wird entwickelt', 'abgeschlossen']

    const taskColumnList = statusList.map((status, index) => {
        zurückkehren {
            Name: Status,
            Liste: Taskliste.Filter(Element => Element.Status === Status),
            ID: Index
        }
    })

    const PrioritätMap = {
        'P0': {
            Label: "Höchste Qualität",
            Farbe: '#ff5454',
        },
        'P1': {
            Etikett: „Hohe Qualität“,
            Farbe: '#ff9a00',
        },
        'P2': {
            Bezeichnung: 'Mittel',
            Farbe: '#ffd139',
        },
        'P3': {
            Bezeichnung: 'niedriger',
            Farbe: '#1ac7b5',
        },
    }

    Standard exportieren {
        Name: 'Karten',
        Komponenten: {Container, Draggable},
        Daten () {
            zurückkehren {
                Aufgabenspaltenliste,
                Prioritätskarte,
                Platzhalteroptionen löschen: {
                    Klassenname: "Drop-Preview",
                    Animationsdauer: '150',
                    showOnTop: wahr
                }
            }
        },
        Methoden: {
            beiSpaltenabfall (dropResult) {
                this.taskColumnList = draggen(this.taskColumnList, dropResult)
            },
            onCardDrop (Spalten-Id, Drop-Ergebnis) {
                let { entfernterIndex, hinzugefügterIndex, Nutzlast } = dropResult
                wenn (entfernterIndex !== null || hinzugefügterIndex !== null) {
                    const Spalte = TaskColumnList.find(p => p.id === Spalten-Id)
                    if (addedIndex !== null && payload) { // Aufgabenstatus aktualisieren dropResult.payload = {
                            ...Nutzlast,
                            Status: Spaltenname,
                        }
                    }
                    Spalte.Liste = applyDrag(Spalte.Liste, dropResult)
                }
            },
            getCardPayload (Spalten-ID) {
                Rückgabeindex =>
                    diese.taskColumnList.find(p => p.id === columnId).list[index]
            },
        }
    }
</Skript>


<Stil>
    * {
        Rand: 0;
        Polsterung: 0;
        Schriftfamilie: „Microsoft YaHei“, „PingFang SC“, „Helvetica Neue“, Helvetica, serifenlos;
        Zeilenhöhe: 1,45;
        Farbe: rgba(0,0,0,.65);
    }
    .Kartenszene {
        Benutzerauswahl: keine;
        Anzeige: Flex;
        Höhe: 100%;
        Rand: 20px;
    }
    .Kartencontainer {
        Anzeige: Flex;
        Flex-Richtung: Spalte;
        Breite: 260px;
        Mindestbreite: 260px;
        Rahmenradius: 12px;
        Hintergrundfarbe: #edeff2;
        Rand rechts: 16px;
        Höhe: berechnet (100vh – 40px);
    }
    .Kartenspaltenkopfzeile {
        Anzeige: Flex;
        Höhe: 50px;
        Rand: 0 16px;
        Elemente ausrichten: zentrieren;
        Flex-Schrumpfen: 0;
        Schriftstärke: 500;
        Schriftgröße: 16px;
    }
    .ziehbarer-Container {
        Flex-Wachstum: 1;
        Überlauf: automatisch;
    }
    .Spaltenziehgriff {
        Cursor: bewegen;
        Polsterung: 5px;
    }
    .Aufgabenkarte {
        Rand: 10px;
        Hintergrundfarbe: weiß;
        Polsterung: 15px 10px;
        Rahmenradius: 8px;
        Kastenschatten: 0 1px 2px 0 rgba (0, 0, 0, 0,12);
        Cursor: Zeiger;
        Anzeige: Flex;
        Inhalt ausrichten: Abstand dazwischen;
    }
    .Aufgabentitel {
        Farbe: #333333;
        Schriftgröße: 14px;
    }
    .Aufgabenpriorität {
        Breite: 60px;
        Zeilenhöhe: 20px;
        Rahmenradius: 12px;
        Textausrichtung: zentriert;
        Farbe: #fff;
        Schriftgröße: 12px;
    }
    .Kartengeist {
        Übergang: Transformation 0,18 s einfach;
        transformieren: drehenZ(5 Grad)
    }

    .Karte-Geister-Drop {
        Übergang: Transformation 0,18 s, leichtes Ein- und Aussteigen;
        transformieren: drehenZ(0 Grad)
    }

    .drop-vorschau {
        Hintergrundfarbe: rgba(150, 150, 200, 0,1);
        Rand: 1px gestrichelt #abc;
        Rand: 5px;
    }
</Stil>

Wirkung

Dies ist das Ende dieses Artikels über die detaillierte Verwendung von Vue Smooth DnD, einer verschiebbaren Komponente von Vue. Weitere verwandte Inhalte zu verschiebbaren Vue-Komponenten finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder durchsuchen Sie die folgenden verwandten Artikel weiter. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Vue Drag-Komponente Vuedraggable API-Optionen zum gegenseitigen Ziehen und Sortieren zwischen Boxen
  • Vue-Drag-Komponentenliste zum Realisieren einer dynamischen Seitenkonfigurationsfunktion
  • Detaillierte Erklärung zur Verwendung der Vue-Drag-Komponente
  • Detaillierte Erläuterung des Vue-Drag-Komponenten-Entwicklungsbeispiels
  • Vue implementiert die Anforderung des Ziehens und Ablegens dynamisch generierter Komponenten
  • Vue verwendet Split, um die universelle Drag-and-Slide-Partitionspanel-Komponente zu kapseln
  • Vue entwickelt eine Drag-Fortschrittsbalken-Schiebekomponente
  • vue draggable resizable realisiert die Komponentenfunktion der draggable-Skalierung
  • Verwenden Sie die Vue-Draggable-Komponente, um die Drag & Drop-Sortierung von Tabelleninhalten im Vue-Projekt zu implementieren
  • Die Vue-Komponente Draggable implementiert die Drag-Funktion
  • So implementieren Sie verschiebbare Komponenten in Vue

<<:  Installations-Tutorial für MySQL 8.0.15-Version: Verbindung zu Navicat.list herstellen

>>:  So ändern Sie die Gruppe, zu der ein Benutzer in Linux gehört

Artikel empfehlen

Erfahrungsaustausch über die Priorität des Ladens von CSS-Stilen

Während der Projektentwicklung bin ich gestern auf...

CSS steuert den Abstand zwischen Wörtern durch die Eigenschaft „letter-spacing“

Eigenschaft „letter-spacing“ : Vergrößern oder ve...

react-beautiful-dnd implementiert die Drag-and-Drop-Funktion für Komponenten

Inhaltsverzeichnis 1. Installation 2.API 3. reagi...

Einführung in die JWT-Verifizierung mit Nginx und Lua

Inhaltsverzeichnis Vorwort Lua-Skript nignx.conf-...

Detaillierte Schritte zur Verwendung von Arthas in einem Docker-Container

Was kann Arthas für Sie tun? Arthas ist das Open-...

Ein vollständiges Tutorial zur Verwendung der Axios-Kapselung in Vue

Vorwort Heutzutage wird in Projekten häufig die A...

Tipps zum Organisieren von Zeichenfolgen in Linux

Bei Linux-Operationen ersetzen und zählen wir häu...

Zusammenfassung und Beispiele der Kommunikationsmethoden für Vue3-Komponenten

Die Kommunikationsmodi der Vue3-Komponenten sind ...

Prozessdiagramm für die Ideenbereitstellung und Tomcat-Dienstimplementierung

Konfigurieren Sie zunächst die Projektartefakte K...

So stellen Sie Docker-Containerdaten wieder her

Die Datenbankdaten der Projekttestumgebung sind v...

Eine kurze Einführung in den allgemeinen Prozess der Web-Frontend-Webentwicklung

Ich sehe viele Anfänger in der Front-End-Entwicklu...