Detaillierte Erklärung des Fehlers bei der Verwendung des Element-ui NavMenu-Untermenüs zur rekursiven Generierung

Detaillierte Erklärung des Fehlers bei der Verwendung des Element-ui NavMenu-Untermenüs zur rekursiven Generierung

Wenn das Untermenü der Navigationsleiste rekursiv generiert wird, kann das Menü normal generiert werden. Wenn jedoch mit der Maus darübergefahren wird, wird zyklisch ein bestimmtes (MouseEnter-)Ereignis aufgerufen, was am Ende zu einem Fehler führt

Verarbeitung

Hinweis: In Version 2.13.2 müssen Sie nur das Attribut des Untermenüs festlegen: popper-append-to-body="false", um dieses Problem zu vermeiden.

Die Fehlermeldung lautet:

Nicht abgefangener RangeError: Maximale Aufrufstapelgröße überschritten.
bei VueComponent.handleMouseenter (index.js:1)
bei invokeWithErrorHandling (vue.js:1863)
bei HTMLLIElement.invoker (vue.js:2188)
bei HTMLLIElement.original._wrapper (vue.js:7547)
bei VueComponent.handleMouseenter (index.js:1)
bei invokeWithErrorHandling (vue.js:1863)
bei HTMLLIElement.invoker (vue.js:2188)
bei HTMLLIElement.original._wrapper (vue.js:7547)
bei VueComponent.handleMouseenter (index.js:1)
bei invokeWithErrorHandling (vue.js:1863)

Testcode

Version:

  • Version: v2.6.11
  • Element-Benutzeroberfläche: 2.13.0
<!DOCTYPE html>
<html>
 <Kopf>
  <meta charset="utf-8">
  <Titel></Titel>
  <!-- Stil importieren -->
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" rel="externes nofollow" >
 </Kopf>
 <Text>

  <div id="Wurzel">
   <el-menu mode="horizontal">
    <template v-for="(Menü,Index) in Menüs">
     <Untermenü v-if="Menü.Kinder && Menü.Kinder.Länge" :Schlüssel="Index" :Element="Menü"></Untermenü>
     <el-menu-item v-else :index="menu.path" :key="index">{{ menu.title }}</el-menu-item>
    </Vorlage>
   </el-Menü>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <!-- Komponentenbibliothek importieren-->
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <Skripttyp="text/javascript">
   Vue.component('Untermenü', {
    Requisiten: ['Artikel'],
    Vorlage: `
     <el-submenu :index="item.pfad">
      <Vorlagenslot="Titel">
       {{item.title}}
      </Vorlage>
      <template v-for="(Kind,Index) in Element.Kinder">
       <Untermenü v-if="Kind.Kinder" :item="Kind" :key="index"></Untermenü>
       <el-menu-item v-else :key="index" :index="child.path">
        {{child.title}}
       </el-Menüelement>
      </Vorlage>
     </el-Untermenü>
    `
   })

   lass vm = neues Vue({
    el: "#Wurzel",
    Daten() {
     zurückkehren {
      Menüs: [{
       Titel: 'Meine Werkbank',
       Pfad: '2',
       Kinder: [{
         Titel: „Option 1“,
         Pfad: '2-1'
        },
        {
         Titel: „Option 2“,
         Pfad: '2-2',
        },
       ],
      },{
       Titel: „Hintergrundverwaltung“,
       Pfad:'3'
      }]
     }
    },
    Komponenten: {}
   })
  </Skript>
 </body>
</html>

Fehleranalyse

Beachten Sie den rekursiv generierten Navigationsleistencode und Fehlercode:

 handleMouseenter: Funktion(e) {
                    var t = dies
                      , i = Argumente.Länge > 1 und void 0 !== Argumente[1] ? Argumente[1] : this.showTimeout;
                    wenn ("ActiveXObject" im Fenster || "Fokus" !== e.Typ || e.relatedTarget) {
                        var n = dieses.rootMenu
                          , r = dies.deaktiviert;
                        "Klicken" === n.menuTrigger && "horizontal" === n.mode || !n.collapse && "vertikal" === n.mode || r || (this.dispatch("ElSubmenu", "mouse-enter-child"),
                        Zeitüberschreitung löschen(diese.Zeitüberschreitung),
                        dies.timeout = setzeTimeout(Funktion() {
                            t.rootMenu.openMenu(t.index, t.indexPath)
                        }, ich),
                        this.appendToBody && this.$parent.$el.dispatchEvent(new MouseEvent("mouseenter")));//Fehlercode}
                },

Ich vermute, es liegt daran, dass das Aufsteigen oder Absinken von Ereignissen dazu führt, dass das Element wiederholt MouseEnter-Ereignisse versendet und empfängt, was zu einem Zustand ähnlich einer Endlosschleife führt. Aus Zeitgründen bin ich nicht näher darauf eingegangen. Ich werde die Grundursache später überprüfen, wenn ich Zeit habe (falls ich daran denke ...)

Wenn die Maus in das Menü bewegt wird, wird die Methode handleMouseenter ausgelöst, aber weil appendToBody wahr ist, wird das Mauseingabeereignis erneut ausgelöst und kehrt dann zu dieser Methode zurück, was zu einer Endlosschleife führt. appendToBody ist eine berechnete Eigenschaft. Warum ist appendToBody also wahr? Schauen Sie sich den Code an:

{
 Name: 'ElSubmenu',
    Komponentenname: 'ElSubmenu',
 Requisiten:{
  popperAnfügenToBody: {
         Typ: Boolean,
         Standard: nicht definiert   
        }
    },
    berechnet:{
  anfügenZuBody() {
        returniere this.popperAppendToBody === undefiniert     
          ? this.isFirstLevel //Wenn popperAppendToBody nicht explizit angegeben ist, berechnen Sie diesen Wert: this.popperAppendToBody;
      },
      istErstesLevel() {
        sei isFirstLevel = true;
        lass übergeordnetes Element = dies.$übergeordnetes Element;
        während (übergeordnetes Menü && übergeordnetes Menü !== dieses.Stammmenü) {
        
        //Berechnen, ob das aktuelle Menü die erste Ebene ist.
        //Es scheint in Ordnung zu sein, da der Code angegeben hat, dass der aktuelle Komponentenname componentName: 'ElSubmenu' ist. Beim Debuggen wurde jedoch festgestellt, dass der Wert von componentName nicht definiert ist. Unabhängig von der Ebene lautet das Endergebnis also isFirstLevel = true. 
          if (['ElSubmenu', 'ElMenuItemGroup'].indexOf(parent.$options.componentName) > -1) {
            istErstesLevel = falsch;
            brechen;
          } anders {
            Elternteil = Elternteil.$Elternteil;
          }
        }
        gibt isFirstLevel zurück;
      }
 }
}

Warum Vue diesen Parameter bei der Registrierung der Komponente nicht erfasst hat, müssen wir uns noch den Quellcode ansehen. Die Mittagspause ist vorbei und ich muss weiter codieren ... Ich werde es noch einmal analysieren, wenn ich Zeit habe ...

Verarbeitung

Fügen Sie dem el-submenu ein Attribut hinzu: popper-append-to-body="true false", um appendToBody explizit als false anzugeben.

Besondere Entschuldigungen:

Die vorherige Verarbeitungsmethode wurde falsch geschrieben. Sie wurde wie folgt geschrieben: popper-append-to-body="true". Daher wird auch dann ein Fehler gemeldet, wenn dieses Attribut hinzugefügt wird. Ich entschuldige mich dafür!

Dies ist das Ende dieses Artikels mit der detaillierten Erklärung des Fehlers bei der rekursiven Generierung des Element-ui NavMenu-Untermenüs. Weitere relevante Inhalte zur rekursiven Generierung des Element-ui NavMenu-Untermenüs finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den verwandten Artikeln weiter unten. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Lösung zum Hervorheben der Vue+Element-Navigationsleiste
  • Element-Ui-Komponente NavMenu spezifische Verwendung des Navigationsmenüs
  • Beheben Sie das Problem, dass das Navigationsmenü nach dem Aktualisieren des Vue-Projekts an der falschen Position hervorgehoben wird
  • Lösen Sie das Problem der Hervorhebung des NavMenu-Navigationsmenüs in Elementui (lösen Sie mehrere Situationen).

<<:  Detailliertes Beispiel für MySQL-Datenspeicherprozessparameter

>>:  VMware Workstation 14 Pro installiert CentOS 7.0

Artikel empfehlen

Versionsnummern in CSS- und JS-Links in HTML (Cache aktualisieren)

Hintergrund Suchen Sie in der Suchmaschine nach d...

JS implementiert einen einfachen Zähler

Verwenden Sie HTML, CSS und JavaScript, um einen ...

CSS HACK für IE6/IE7/IE8/IE9/FF (Zusammenfassung)

Seit ich die offizielle Version von IE8.0 install...

Detaillierte Erläuterung der Verwendung des MySQL-Auswahl-Cache-Mechanismus

Der MySQL-Abfragecache ist standardmäßig aktivier...

JavaScript implementiert einen langen Bild-Scroll-Effekt

In diesem Artikel wird der spezifische Code für d...

Verwendung des Linux-Datumsbefehls

1. Befehlseinführung Mit dem Datumsbefehl wird di...

Beispiel für die Anpassung des Vue-Projekts an den großen Bildschirm

Eine kurze Analyse von rem Zunächst einmal ist re...

So öffnen Sie eine Seite in einem Iframe

Lösung: Setzen Sie den Zielattributwert des Links ...

Lösen Sie das Problem verschwindender Docker-Images

1. Spiegelbilder verschwinden in 50 und 93 [root@...

Zusammenfassung der @-Verwendung in CSS (mit Beispielen und Erklärungen)

Eine At-Regel ist eine Deklaration, die Anweisung...

Zusammenfassung der MySQL-Ansichtsprinzipien und Anwendungsbeispiele

Dieser Artikel fasst die Prinzipien und die Verwe...

Diskussion zur horizontalen und vertikalen Zentrierung von Elementen in HTML

Beim Entwerfen einer Seite müssen wir das DIV häu...