Informationen zum Fallstrickprotokoll der Vue3-Übergangsanimation

Informationen zum Fallstrickprotokoll der Vue3-Übergangsanimation

Hintergrund

Im Q&A-Bereich meines Kurses „Vue 3 Entwickeln von Musik-Apps auf Unternehmensebene“ stellte ein Kommilitone eine Frage. In der Übergangsanimation von der Sängerliste zur Sängerdetailseite gibt es nur eine Einstiegsanimation, aber keine Ausstiegsanimation:

Der Student hatte tatsächlich einige Zeit an diesem Problem gearbeitet, und aus seiner Beschreibung konnte ich eine Zeit lang nicht erkennen, wo das Problem lag, also bat ich ihn, den Code auf GitHub hochzuladen. Schließlich ist es am zuverlässigsten, das Problem direkt auf Codeebene zu lokalisieren.

Problemort

Wenn ich auf solche Probleme stoße, ist meine erste Reaktion im Allgemeinen, dass es möglicherweise Probleme mit der von ihm verwendeten Vue 3-Version gibt. Schließlich befindet sich Vue 3 noch im Prozess der kontinuierlichen Iteration, und es ist normal, dass eine bestimmte Version einige kleinere Fehler aufweist. Daher habe ich die Vue 3-Version seines Projekts auf die neueste Version 3.2.26 aktualisiert.

Aber nachdem ich es ausgeführt hatte, stellte ich fest, dass das Problem weiterhin besteht. Ich war etwas verwirrt und habe den Quellcode meines Kursprojekts ausgeführt, konnte das Problem jedoch nicht reproduzieren. Dann habe ich die Vue 3-Version meines Kursprojekts auf die neueste Version aktualisiert, konnte das Problem jedoch immer noch nicht reproduzieren.

Durch die obige Analyse habe ich das Problem der Vue 3-Version grundsätzlich ausgeschlossen. Im Wesentlichen bedeutet der Wechsel von der Sängerseite zur Sängerdetailseite nichts anderes als das Öffnen der Sängerdetailseite, einer sekundären Routingseite, und die Rückkehr von der Sängerdetailseite zur Sängerseite bedeutet nichts anderes als das Entfernen der Sängerdetailseite, einer sekundären Routingseite. Also begann ich, den Quellcode der Sängerseite und der Detailseite der beiden Projekte zu vergleichen:

<!-- Sänger.vue -->

<Vorlage>

<div class="singer" v-loading="!singers.length">

  <index-liste

    :data="Sänger"

    @select="Sänger auswählen"

  ></index-liste>

  <!-- Verwenden Sie die Router-Ansicht, um sekundäres Routing durchzuführen -->

<!-- <router-view :singer="selectedSinger"></router-view>-->

  <!-- Vue3 muss in der Router-Ansicht einen Übergang verwenden. Beim Eintreten von „apple“ wird eine Animation angezeigt -->

  <router-view v-slot="{ Komponente }">

<!-- singer-detail gibt Animation ungültige Recherche zurück -->

    <Übergang erscheint Name="Folie">

      <!-- Komponente dynamische Komponente Komponente ist eine Eigenschaft im Bereichsslot, die von der Router-View-Gruppe bereitgestellt wird. Komponente ist die Routing-Komponente in Ihrer Routing-Tabelle exclude="singer-detail" schließt Komponenten aus, die keine Daten zwischenspeichern, andernfalls werden die Daten zwischengespeichert, sodass nicht jedes Mal eine erneute Anforderung erfolgt -->

        <Komponente: ist = "Komponente"

                   :singer="ausgewählterSänger"

        ></Komponente>

    </Übergang>

  </Router-Ansicht>

</div>

</Vorlage>



<!-- Sänger-Detail.vue -->

<Vorlage>

  <!-- Da es über sekundäres Routing implementiert wird, wird es unter Ansichten platziert-->

  <Abschnitt Klasse="Sänger-Detail">

    <Musikliste

      :songs="Lieder"

      :title="Titel"

      :pic="Bild"

      :wird geladen="wird geladen"

    ></Musikliste>

  </Abschnitt>

</Vorlage>

Oben ist der Code des Studenten. Als Nächstes füge ich den Quellcode meines Projekts ein:

<!-- Sänger.vue -->

<Vorlage>

  <div class="singer" v-loading="!singers.length">

    <index-liste

      :data="Sänger"

      @select="Sänger auswählen"

    ></index-liste>

    <router-view v-slot="{ Komponente }">

      <Übergang erscheint Name="Folie">

        <component :is="Komponente" :data="selectedSinger"/>

      </Übergang>

    </Router-Ansicht>

  </div>

</Vorlage>

<!-- singer-detail.vue -->

<Vorlage>

  <div Klasse="Sänger-Detail">

    <Musikliste

      :songs="Lieder"

      :title="Titel"

      :pic="Bild"

      :wird geladen="wird geladen"

    ></Musikliste>

  </div>

</Vorlage>

Nach dem Vergleich habe ich den Eindruck, dass sich der Quellcode auf beiden Seiten nicht sehr unterscheidet, außer dass die Schüler Kommentare verwenden, um einige Lernnotizen zu machen. Da es zunächst schwierig war, das Problem zu finden, habe ich meinen besten Trick angewendet: das Debuggen des Quellcodes. Schließlich kenne ich die Implementierungsprinzipien der Übergangsanimation von Vue 3 sehr gut.

Wenn die Exit-Übergangsanimation ausgeführt wird, wird die Leave-Hook-Funktion ausgeführt, die aus dem von der Übergangskomponente umschlossenen untergeordneten Knoten analysiert wird.

Daher habe ich innerhalb der Leave-Hook-Funktion einen Debugger-Haltepunkt hinzugefügt:

// @vue/runtime-core/dist/runtime.core-bundler.esm.js

verlassen(el, entfernen) {

  Debugger

  const key = String(vnode.key);

  wenn (el._enterCb) {

    el._enterCb(true /* abgebrochen */);

  }

  // ...

}

Dann führe ich das Projekt aus. Wenn ich von der Sängerdetailseite zur Sängerseite zurückkehre, stelle ich fest, dass ich den Debugger-Haltepunkt nicht eingegeben habe, was bedeutet, dass die Leave-Hook-Funktion überhaupt nicht ausgeführt wurde.

Um noch weiter zurückzugehen: Für den Knoten, der gerade deinstalliert wird, ist der Zeitpunkt der Ausführung seiner Leave-Hook-Funktion der Ausführung der Remove-Funktion. Deshalb setze ich einen Haltepunkt innerhalb der Remove-Funktion:

// @vue/runtime-core/dist/runtime.core-bundler.esm.js

const entfernen = vnode => {

  Debugger

  const { Typ, el, Anker, Übergang } = vnode;

  wenn (Typ === Fragment) {

    entferneFragment(el, Anker);

    zurückkehren;

  }

  wenn (Typ === Statisch) {

    entferneStaticNode(vnode);

    zurückkehren;

  }

  const performRemove = () => {

    : HostRemove(el);

    wenn (Übergang && !Übergang.persistiert && Übergang.nachVerlassen) {

      Übergang.nachVerlassen();

    }

  };

  wenn (vnode.shapeFlag & 1 /* ELEMENT */ &&

    Übergang &&

    !Übergang.persistent) {

    const { verlassen, VerzögerungVerlassen} = Übergang;

    const performLeave = () => verlassen(el, performRemove);

    wenn (VerzögerungVerlassen) {

      VerzögerungLeave(vnode.el, performRemove, performLeave);

    }

    anders {

      durchführenLeave();

    }

  }

  anders {

    führen SieRemove();

  }

};

Dann habe ich das Projekt erneut ausgeführt. Als ich von der Sängerdetailseite zur Sängerseite zurückkehrte, fand ich, obwohl ich den Haltepunkt eingegeben hatte, auch einige logische Probleme im Code: Das entsprechende Übergangsobjekt wurde vom Vnode analysiert. Da der entsprechende Typ Fragment ist, trat die Ausführung in die folgende Logik ein:

wenn (Typ === Fragment) {

  entferneFragment(el, Anker);

  zurückkehren;

}

Kehrt direkt zurück, ohne die Leave-Hook-Funktion des nachfolgenden Übergangsobjekts auszuführen. Ich habe den Wert von vnode weiter überprüft und festgestellt, dass er zwei untergeordnete Knoten hatte, einen Kommentarknoten und einen Abschnittsknoten. Plötzlich wurde mir klar, dass das Problem durch die Kommentare der Studenten verursacht wurde:

<!-- singer-detail.vue -->

<Vorlage>

  <!-- Da es über sekundäres Routing implementiert wird, wird es unter Ansichten platziert-->

  <Abschnitt Klasse="Sänger-Detail">

    <Musikliste

      :songs="Lieder"

      :title="Titel"

      :pic="Bild"

      :wird geladen="wird geladen"

    ></Musikliste>

  </Abschnitt>

</Vorlage>

Wenn beim Parsen von Vue-Vorlagen HTML-Kommentare auftreten, werden diese ebenfalls in einen Kommentarknoten geparst. Sie können das Vue 3-Vorlagenexporttool verwenden, um das kompilierte Ergebnis anzuzeigen:

importiere { createCommentVNode als _createCommentVNode, resolveComponent als _resolveComponent, createVNode als _createVNode, createElementVNode als _createElementVNode, Fragment als _Fragment, openBlock als _openBlock, createElementBlock als _createElementBlock } von „vue“

const _hoisted_1 = { Klasse: "singer-detail" }

Funktion rendern(_ctx, _cache) {

  const _component_music_list = _resolveComponent("Musikliste")

  return (_openBlock(), _createElementBlock(_Fragment, null, [

    _createCommentVNode("Da es über sekundäres Routing implementiert wird, wird es unter Ansichten platziert"),

    _createElementVNode("Abschnitt", _hoisted_1, [

      _createVNode(_component_music_list, {

        Lieder: _ctx.songs,

        Titel: _ctx.title,

        Bild: _ctx.pic,

        wird geladen: _ctx.loading

      }, null, 8 /* PROPS */, ["Songs", "Titel", "Bild", "wird geladen"])

    ])

  ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */))

}

Da Vue 3 Vorlagen mit mehr als einem Stammknoten unterstützt, wird die Wurzel der obigen Vorlage in einen Fragmentknoten analysiert, was bedeutet, dass die entsprechende Übergangsanimation nicht ausgeführt wird, wenn die Komponente entfernt wird.

Weitere Analyse

Warum benötigen Fragmentknoten keine Übergangsanimationen? Ich habe den Commit-Kommentar zum Code gefunden:

Fix (Fragment): Führen Sie beim Entfernen von Fragmenten eine direkte Entfernung durch. Dadurch wird vermieden, dass versucht wird, .el von angehobenen untergeordneten Knoten zu erfassen (die von einer anderen Instanz erstellt werden können), und außerdem wird die Übergangsprüfung übersprungen, da untergeordnete Fragmente keine Übergänge haben können.

Die im Kommentar gegebene Erklärung ist, dass Fragmentknoten keine Übergänge haben können. Allerdings bleibt hier die Frage, warum das Schreiben davon keinen Einfluss auf den Beginn der Übergangsanimation hat.

Denn wenn die Komponenten-Renderfunktion zur Laufzeit ausgeführt wird, um den Teilbaum subTree der Komponente zu rendern, werden innerhalb der Funktion renderComponentRoot einige spezielle Verarbeitungsvorgänge ausgeführt:

Funktion renderComponentRoot(Instanz) {

  Ergebnis lassen

  // ...

  //Renderfunktion aufrufen, um das Ergebnis zu erhalten

  // Attributzusammenführung

  // im dev-Modus bleiben Kommentare erhalten und es ist möglich, dass eine Vorlage

  // um Kommentare neben dem Stammelement zu haben, die es zu einem Fragment machen

  sei root = Ergebnis;

  let setRoot = undefiniert;

  wenn ((Prozess.env.NODE_ENV !== 'Produktion') &&

    result.patchFlag > 0 &&

    result.patchFlag & 2048 /* DEV_ROOT_FRAGMENT */) {

    [root, setRoot] = getChildRoot(Ergebnis);

  }

  // Übergangsdaten erben

  wenn (vnode.transition) {

    // ...

    root.transition = vnode.transition;

  }

  Ergebnis zurückgeben

}

Nachdem der gerenderte Teilbaum durch Ausführen der Rendermethode der Komponenteninstanz abgerufen wurde, wird der Kommentarknoten durch die Funktion getChildRoot in der Entwicklungsumgebung gefiltert, um die Ergebniswurzel abzurufen, und sein Stammknoten erbt das Übergangsobjekt seines übergeordneten V-Knotens. Beachten Sie jedoch, dass das gesamte renderComponentRoot weiterhin das Ergebnisobjekt zurückgibt.

Für die SingerDetail-Komponente in unserem Beispiel ist ihr untergeordneter V-Knoten ein Fragment. Beim Ausführen von renderComponentRoot wird der erste Knoten jedoch gefiltert, da es sich bei ihm um einen Kommentarknoten handelt. Nur der V-Knoten, der dem nachfolgenden Entitätsknoten „Singer-Detail“ entspricht, verfügt über das Übergangsattribut und tritt daher in die Übergangsanimation ein.

Wenn die Komponente jedoch entfernt wird, erfolgt keine Übergangsanimation beim Verlassen, da der Unterbaum-V-Knoten der Komponente ein Fragment ist.

Zusammenfassen

Nachdem die Ursache des Fehlers gefunden wurde, ist die Behebung sehr einfach. Löschen Sie einfach den Kommentarknoten. In der Produktionsumgebung tritt dieses Problem natürlich nicht auf, da die Produktionsumgebung den Kommentarknoten standardmäßig löscht.

Anhand dieses Falls können wir erkennen, dass das Schreiben von Kommentaren zwar eine gute Angewohnheit ist, Sie jedoch versehentlich in die Fallstricke von Vue 3 tappen können.

Es ist sehr wichtig zu lernen, wie man Quellcode debuggt. Wenn Sie den Quellcode nicht verstehen, werden Sie verwirrt und passiv sein, wenn Sie auf solche Fehler stoßen, weil Ihnen die Dokumentation den Grund nicht verrät. Daher ermutige ich weiterhin alle, den Quellcode genauer zu studieren. Durch das Debuggen des Quellcodes kommen Sie der Wahrheit am nächsten.

Dies ist das Ende dieses Artikels über die Fallstricke der Vue3-Übergangsanimation. Weitere relevante Fallstricke der Vue3-Übergangsanimation finden Sie in den vorherigen Artikeln von 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Detaillierte Erläuterung der Vue3-Übergangsanimation
  • Vue.js muss jeden Tag Übergänge und Animationen lernen
  • Vue-Element zum Erzielen eines Animationsübergangseffekts
  • Vue: Erste Schritte mit animierten Übergangsanimationseffekten
  • Verwenden Sie Übergang und Übergangsgruppe in Vue-Komponenten, um Übergangsanimationen zu implementieren
  • Detaillierte Erläuterung der Übergangskomponente im Fall von Vue Transition (Animation)
  • Zehn Minuten für den schnellen Einstieg in die Vue3-Übergangsanimation

<<:  Implementierung der Nginx-Konfiguration des lokalen Image-Servers

>>:  Was ist HTML?

Artikel empfehlen

Detaillierte Erläuterung der MySQL-Benutzerrechteverwaltung

Inhaltsverzeichnis Vorwort: 1. Einführung in die ...

So richten Sie Spring Boot mithilfe der Docker-Schichtenverpackung ein

Das Spring Boot-Projekt verwendet Docker-Containe...

Ausführliches Tutorial zur Installation von mysql 5.6.23 winx64.zip

Eine ausführliche Dokumentation zur Installation ...

JavaScript zur Implementierung des Countdowns für den SMS-Versand

In diesem Artikel wird der spezifische JavaScript...

jQuery implementiert Navigationsleisteneffekt mit Erweiterungsanimation

Ich habe eine Navigationsleiste mit einem erweite...

Sechs mit CSS3 implementierte Randübergangseffekte

Sechs EffekteImplementierungscode html <h1>...

Detaillierte Erklärung zur Verwendung des Schlüsselworts ESCAPE in MySQL

MySQL-Escape Escape bedeutet die ursprüngliche Se...

Vue verwendet OSS zum Hochladen von Bildern oder Anhängen

Verwenden Sie OSS, um Bilder oder Anhänge in ein ...

Der vollständige Leitfaden zum Rasterlayout in CSS

Grid ist ein zweidimensionales Rasterlayoutsystem...

Verständnis und Anwendung des Destrukturierungsoperators von JavaScript ES6

Inhaltsverzeichnis Vorwort Die Rolle von Dekonstr...

Detaillierte Erläuterung des Selinux-Grundkonfigurationstutorials unter Linux

selinux ( Security-Enhanced Linux) ist ein Linux-...