Die Vue+elementUI-Komponente implementiert rekursiv eine faltbare, dynamische Rendering-Seitenleistennavigation auf mehreren Ebenen

Die Vue+elementUI-Komponente implementiert rekursiv eine faltbare, dynamische Rendering-Seitenleistennavigation auf mehreren Ebenen

Die Funktion wurde schon vor langer Zeit implementiert, aber ich habe festgestellt, dass beim Klicken darauf die Hintergrundfarbe des ausgewählten Menüelements weiß wurde. Ich habe es am Freitag sorgfältig beobachtet und festgestellt, dass es kein Problem mit der Anpassung des Stils war, sondern dass die Option nicht ausgewählt war. Also habe ich die Komponentenrekursion sorgfältig untersucht und meine Gedanken zusammengefasst und aufgezeichnet.

1. Konzept

Rekursion: Einfach ausgedrückt bedeutet Rekursion, sich selbst aufzurufen, genau wie bei Matrjoschkas. Als Kind spielte ich ein Spiel namens Tower of Hanoi, bei dem das rekursive Prinzip verwendet wurde:

Bildbeschreibung hier einfügen

Funktionsrekursion: Die Funktion verwendet den Funktionsnamen, um ihre eigene Komponentenrekursion aufzurufen: Daher wird die Komponentenrekursion durch Verwendung des Namensattributs in der Vue-Komponente implementiert

2. Nachfrage

Implementieren Sie ein faltbares dynamisches Rendering der mehrstufigen Seitenleistennavigation

Analyse

Bildbeschreibung hier einfügen

1. Beachten Sie, dass die Seitenleistennavigation jeweils eine Ebene nach der anderen ist und die zweite Ebene der Wiederholung der ersten Ebene entspricht. 2. Es gibt eine Besonderheit, bei der einige Menüs niedrigere Ebenen haben, während andere dies nicht tun. 3. Dynamisches Rendering bedeutet, dass die Baumtypdaten von der Hintergrundschnittstelle abgerufen und dynamisch gerendert werden. 4. Codeimplementierung 1. Führen Sie zunächst die Demo im Dokument aus, um sie auszuprobieren:

Dokumentation: Elementdokumentation

2. Ändern Sie es in den gewünschten Stil. So wurde es zum ersten Mal geschrieben.

Übergeordnete Komponente SideBar

<Vorlage>
  <el-menu class="menu-wrap" :default-active="MenüAktivName || 'home'" :active="MenüAktivName || 'home'"
           :collapse="sidebarFold" :collapseTransition="false" :unique-opened="true" @select="selectItem">
    <Vorlage>
      <el-menu-item @click="sidebarFold = !sidebarFold">
        <i v-show="!sidebarFold" class="el-icon-s-fold"></i>
        <i v-show="sidebarFold" class="el-icon-s-unfold"></i>
        <span slot="title" class="sidebar-one">Navigationsliste</span>
      </el-Menüelement>
    </Vorlage>
<!-- <side-bar-item :list="menuList"></side-bar-item>-->
    <template v-for="(Element, Index) in Menüliste" Klasse="Menü">
      <!-- Titel -->
      <template v-if="item.children.length" >
        <el-submenu :key="index" :index="item.id" class="untermenü-item">
          <template :index="item.index" slot="Titel">
            <!-- <i :class="item.icon"></i>-->
            <i class="iconfont icon-danganjianying"></i>
            <span>{{item.name}}</span>
          </Vorlage>
          <el-menu-item-group class="Menüelementgruppe">
            <side-bar-item :list="item.children"></side-bar-item>
          </el-Menüelementgruppe>
        </el-Untermenü>
      </Vorlage>
      <!-- Optionen -->
      <Vorlage v-else>
        <el-menu-item :key="index" :index="item.id" class="menu-item">
          <!-- <i :class="item.icon"></i>-->
          <i class="iconfont icon-danganjianying"></i>
          <span>{{item.name}}</span>
        </el-Menüelement>
      </Vorlage>
    </Vorlage>
  </el-Menü>
</Vorlage>

<Skript>

Standard exportieren {
  Name: "SideBar",
  Komponenten:
    SideBarItem: () => import('@/components/common/SideBarItem')
  },
  Daten () {
    zurückkehren {

    }
  },
  montiert () {
  },
  Methoden: {
    selectItem(Name, Pfad){
      // Alarm(Name)
      this.$router.push(Pfad)
      dies.$store.commit('common/updateMenuActiveName', Name)
    }
  },
  berechnet: {
    Menüliste: {
      erhalten () {
        gib dies zurück.$store.state.common.menuList
      },
      setze (Wert) {
        dies.$store.commit('common/updateMenuList', Wert)
      }
    },
    MenüAktivName: {
      get () { returniere dies.$store.state.common.menuActiveName},
      setze (Wert) { this.$store.commit('common/updateMenuActiveName', Wert) }
    },
    Seitenleiste einklappen: {
      get() {return this.$store.state.common.sidebarFold;},
      setze(Wert) {this.$store.commit("common/updateSidebarFold", Wert);}
    },
  },
}
</Skript>
<style lang="less" scoped>
.menu-wrap{
  Breite: 200px;
  Mindesthöhe: 1020px;
  Hintergrund: URL('../../assets/img/sidebar_bg.png') keine Wiederholung;
  Hintergrundgröße: 100 % 100 %;
}

/deep/ .el-menu{
  Hintergrundfarbe: transparent !wichtig;
  .iconfont {
    Schriftgröße: 18px;
    vertikale Ausrichtung: Unter;
    Rand rechts: 5px;
    Anzeige: Inline-Block;
    Breite: 20px;
    Textausrichtung: zentriert;
  }
}

/deep/ .el-menu-item,
/deep/ .el-submenu__title{
  Farbe: #fff;

  .iconfont{
    Farbe: #fff;
  }
}

/deep/ .el-menu-item span,
/deep/ .el-submenu__title span{
  Polsterung links: 10px;
}

/deep/ .el-menu-item.is-active {
  -webkit-box-shadow: Einschub 5px 100px 0px -2px #0064B6;
  Box-Shadow: Einschub 5px 100px 0px -2px #0064B6;
}

/deep/ .el-submenu__title:hover,
/deep/ .el-menu-item:hover{
  Hintergrund: #0064B6;
}

/deep/ .el-menu-item-group__title{
  Polsterung: 0;
}

</Stil>

Unterkomponente SideBarItem

<Vorlage>
  <div Klasse="Menü">
    <template v-for="(Element,Index) in Liste">
      <!-- Titel -->
      <template v-if="item.children.length" >
        <el-submenu :key="index" :index="item.id" class="untermenü-item">
          <template :index="item.index" slot="Titel">
<!-- <i :class="item.icon"></i>-->
            <i class="iconfont icon-danganjianying"></i>
            <span>{{item.name}}</span>
          </Vorlage>
          <el-menu-item-group class="Menüelementgruppe">
            <side-bar-item :list="item.children"></side-bar-item>
          </el-Menüelementgruppe>
        </el-Untermenü>
      </Vorlage>
      <!-- Optionen -->
      <Vorlage v-else>
        <el-menu-item :key="index" :index="item.id" class="menu-item" @click="selectItem(item.name, item.path)">
<!-- <i :class="item.icon"></i>-->
          <i class="iconfont icon-danganjianying"></i>
          <span>{{item.name}}</span>
        </el-Menüelement>
      </Vorlage>
    </Vorlage>
  </div>
</Vorlage>
<Skript>

Standard exportieren {
  Name: "SideBarItem",
  // Requisiten: ['Liste'],
  Requisiten: {
    Liste: {
      Typ: Array || ''
    }
  },
  Daten () {
    zurückkehren {
      Baumdaten: [{
        Bezeichnung: 'Provinz',
        Kinder: [{
          Etikett: „Provinzkomitee der Kommunistischen Partei Chinas“
          // Kinder: [{
          // Bezeichnung: „Level 3 1-1-1“
          // }]
        }, {
          Bezeichnung: „Provinzbüro der Kommunistischen Partei Chinas“
        }, {
          Bezeichnung: „Organisationsabteilung einer bestimmten Provinz der Kommunistischen Partei Chinas“
        }
        ]
      }
      ],
      isShow: false
      // Menüliste: []
    }
  },
  montiert () {
    dies.loadSysMenu()
  },
  Methoden: {
    ladeSysMenu () {
      // console.log('Menü', diese.Menüliste)
    },
    // personManage (Name) {
    // if (name === 'Personalverwaltung') {
    // dies.istShow = !this.$store.state.common.rbflag
    // // Alarm('111' + this.isShow)
    // dies.$store.commit('common/updateShowRbox', dies.isShow)
    // }
    // },
    selectItem(Name, Pfad){
      // Alarm(Name)
      this.$router.push(Pfad)
      dies.$store.commit('common/updateMenuActiveName', Name)
    }
  },
}
</Skript>
<style lang="less" scoped>
.Speisekarte{
  Breite: 100 %;

  .Untermenüelement /deep/ .el-submenu__title,
  .Menüpunkt{
    Höhe: 60px;
    Zeilenhöhe: 60px;
    Textausrichtung: links;
    //Auffüllung links: 30px !wichtig;
    //Rahmen unten: 1px durchgezogen #000;
    //Rahmen rechts: 1px durchgezogen #000;
    Farbe: #fff;
  }

  .Untermenüelement .el-Menüelement{
    Polsterung rechts: 0;
  }

 /deep/ .el-menu-item .ist-aktiv{
    Hintergrundfarbe: #0087df;
  }

  .Menüpunkt:hover,
  /deep/ .el-submenu__title:hover{
    Hintergrundfarbe: #0087df;
  }

  .Menüpunktspanne,
  .Untermenüelement /deep/ .el-submenu__title>span{
    Schriftstärke: 700;
  }

  .Menüelementgruppe /deep/ .el-Menüelementgruppe__title{
    Polsterung: 0 !wichtig;
  }

  .Menüelementgruppe .Menüelement{
    Hintergrund: URL('../../assets/img/sidebar_bg.png') keine Wiederholung;
  }

  .el-menu-item-group span{
    Schriftstärke: normal;
  }

}

</Stil>

Später stellte ich fest, dass das Falten nicht erfolgreich war und sich der Stil des ausgewählten Elements nach der Auswahl nicht änderte. Später stellte ich fest, dass es nicht ausgewählt war. Nach Recherchen stellte ich fest, dass dies daran lag, dass eine zusätzliche Div-Ebene verschachtelt war und das Projekt el-menu-item-group dies nicht benötigte. Daher war die Verbesserung wie folgt:

Übergeordnete Komponente SideBar

<Vorlage>
  <el-menu class="menu-wrap" :default-active="menuActiveName" :collapse="sidebarFold" :collapseTransition="false" :unique-opened="true">
    <Vorlage>
      <el-menu-item @click="foldSideBar">
        <i v-show="!sidebarFold" class="el-icon-s-fold"></i>
        <i v-show="sidebarFold" class="el-icon-s-unfold"></i>
        <span slot="title" class="sidebar-one">Navigationsliste</span>
      </el-Menüelement>
    </Vorlage>
    <side-bar-item v-for="Menü in Menüliste" :key="menu.id" :menu="Menü"></side-bar-item>
  </el-Menü>
</Vorlage>

<Skript>

Standard exportieren {
  Name: "SideBar",
  Komponenten:
    SideBarItem: () => import('@/components/common/SideBarItem')
  },
  Daten () {
    zurückkehren {
    }
  },
  montiert () {
  },
  Methoden: {
    foldSideBar(){
      this.sidebarFold = !this.sidebarFold
      this.menuActiveName = "NAV"
    }
  },
  berechnet: {
    Menüliste: {
      erhalten () {
        gib dies zurück.$store.state.common.menuList
      },
      setze (Wert) {
        dies.$store.commit('common/updateMenuList', Wert)
      }
    },
    MenüAktivName: {
      erhalten () {
        Konsole.log(dies.$store.state.common.menuActiveName)
        gib dies zurück.$store.state.common.menuActiveName
      },
      setze (Wert) {
        dies.$store.commit('common/updateMenuActiveName', Wert)
      }
    },
    Seitenleiste einklappen: {
      get() {return this.$store.state.common.sidebarFold;},
      setze(Wert) {this.$store.commit("common/updateSidebarFold", Wert);}
    },
  },
}
</Skript>
<style lang="less" scoped>
.menu-wrap{
  Breite: 200px;
  Mindesthöhe: 1020px;
  Hintergrund: URL('../../assets/img/sidebar_bg.png') keine Wiederholung;
  Hintergrundgröße: 100 % 100 %;
}

/deep/ .el-menu{
  Hintergrundfarbe: transparent !wichtig;
  .iconfont {
    Schriftgröße: 18px;
    vertikale Ausrichtung: Unter;
    Rand rechts: 5px;
    Anzeige: Inline-Block;
    Breite: 20px;
    Textausrichtung: zentriert;
  }
}

/deep/ .el-menu-item,
/deep/ .el-submenu__title{
  Farbe: #fff;

  .iconfont{
    Farbe: #fff;
  }
}

/deep/ .el-menu-item span,
/deep/ .el-submenu__title span{
  Polsterung links: 10px;
}

/deep/ .el-menu-item.is-active {
  -webkit-box-shadow: Einschub 5px 100px 0px -2px #0064B6;
  Box-Shadow: Einschub 5px 100px 0px -2px #0064B6;
}

/deep/ .el-submenu__title:hover,
/deep/ .el-menu-item:hover{
  Hintergrund: #0064B6;
}

</Stil>

Unterkomponente SideBarItem

<Vorlage>
    <!-- Unter diesem Menü befinden sich Untermenüs-->
    <el-submenu v-if="Menü.Kinder.Länge" :index="Menü.Code" :popper-append-to-body=false>
        <Vorlagenslot="Titel">
            <i class="iconfont icon-danganjianying"></i>
            <span>{{ menü.name }}</span>
        </Vorlage>
        <side-bar-item v-for="Element in Menü.Kinder" :key="Element.id" :menu="Element"></side-bar-item>
    </el-Untermenü>
    <!-- Unter diesem Menü gibt es kein Untermenü-->
    <el-menu-item v-else :index="menu.code" @click="selectItem(menu.code, menu.path)">
        <i class="iconfont icon-danganjianying"></i>
        <span>{{ menü.name }}</span>
    </el-Menüelement>
</Vorlage>
<Skript>

Standard exportieren {
  Name: "SideBarItem",
  // Requisiten: ['Menü'],
  Requisiten: {
      Speisekarte:
      Typ: Objekt || {}
    }
  },
  Daten () {
    zurückkehren {

    }
  },
  montiert () {
  },
  Methoden: {
    selectItem(Code, Pfad){
      // Alarm(Name)
      console.log(Code, Pfad)
      this.$router.push(Pfad)
      dies.$store.commit('common/updateMenuActiveName', Code)
    }
  },
}
</Skript>
<style lang="less" scoped>
.Speisekarte{
  Breite: 100 %;

  .Menüpunkt{
    Höhe: 60px;
    Zeilenhöhe: 60px;
    Textausrichtung: links;
    Farbe: #fff;
  }

  .Untermenüelement .el-Menüelement{
    Polsterung rechts: 0;
  }

 /deep/ .el-menu-item .ist-aktiv{
    Hintergrundfarbe: #0087df;
  }

  .Menüpunkt:hover{
    Hintergrundfarbe: #0087df;
  }

  .Menüpunkt span{
    Schriftstärke: 700;
  }

}

</Stil>

Die Funktion ist grundsätzlich implementiert, aber es gibt einen Fehler. Wenn die Maus auf die Falte klickt, wird ein bestimmtes Ereignis zyklisch aufgerufen, was zu einem Stapelüberlauffehler führt. Um den Artikel anzuzeigen, setzen Sie einfach das Attribut des Untermenüs: popper-append-to-body="false". Siehe den Artikel: Element-ui NavMenu-Untermenü verwendet rekursive Generierung, um Fehler zu verwenden

Fügen Sie abschließend einige einfache Testdaten an:

Testdaten: [
            {"id": "34161C2E8-7348-4439-8899-9A8039AE6AE4", "pid": "0", "code": "HOME", "name": "Home", "path": "/home", "type": null, "icon": null, "sysId": "2761C2E8-7348-4439-8899-9A8039AE6AE3", "orderNo": 0, "isCheck": null, "children": []},
            {"id":"703DBEBD-F92C-4347-9203-F60A73153C3F","pid":"0","code":"WD","name":"Temperatur","path":"/temperatur","type":null,"icon":null,"sysId":"2AB00274-73DF-459A-A02E-C79A4D8A8929","orderNo":0,"isCheck":null,"children":[]},
            {"id":"73660AB4-48D3-4BDB-86FD-C8397D4D54EC","pid":"0","code":"BJ","name":"Alarm","path":"/alarm","type":null,"icon":null,"sysId":"2AB00274-73DF-459A-A02E-C79A4D8A8929","orderNo":0,"isCheck":null,
              "Kinder":[
                {"id":"1C99333D-886F-4AD6-93C4-7C5244E48247","pid":"73660AB4-48D3-4BDB-86FD-C8397D4D54EC","code":"FD","name":"Diebstahlschutz","path":"/burg","type":null,"icon":null,"sysId":"3691C2E8-8848-4439-8899-9A8039AE6AB5","orderNo":0,"isCheck":null,"children":[]},
                {"id":"1DBDF678-F51F-444A-B995-61E5D9CCA5AF","pid":"73660AB4-48D3-4BDB-86FD-C8397D4D54EC","code":"JL","name":"Alarmglocke","path":"/glocke","type":null,"icon":null,"sysId":"3691C2E8-8848-4439-8899-9A8039AE6AB5","orderNo":0,"isCheck":null,"children":[]},
                {"id":"BFC8C2E1-0E5B-4EEE-B91D-3DABC63FF481","pid":"73660AB4-48D3-4BDB-86FD-C8397D4D54EC","code":"JS","name":"immersion","path":"/immersion","type":null,"icon":null,"sysId":"3691C2E8-8848-4439-8899-9A8039AE6AB5","orderNo":0,"isCheck":null,"children":[]},
                {"id":"BFC8C2E1-0E5B-4EEE-B91D-3DABC63FF482","pid":"73660AB4-48D3-4BDB-86FD-C8397D4D54EC","code":"MJ","name":"Zugriffskontrolle","path":"/punch","type":null,"icon":null,"sysId":"3691C2E8-8848-4439-8899-9A8039AE6AB5","orderNo":0,"isCheck":null,"children":[]},
                {"id":"BFC8C2E1-0E5B-4EEE-B91D-3DABC63FF483","pid":"73660AB4-48D3-4BDB-86FD-C8397D4D54EC","code":"ZT","name":"Bundesstaat","path":"/bundesstaat","typ":null,"icon":null,"sysId":"3691C2E8-8848-4439-8899-9A8039AE6AB5","orderNo":0,"isCheck":null,"children":[]}
              ]
            },
            {"id":"34161C2E8-7348-4439-8899-9A8039AE6AE5","pid":"0","code":"GZ","name":"Arbeit","path":"/arbeit","typ":null,"icon":null,"sysId":"3691C2E8-8848-4439-8899-9A8039AE6AB5","orderNo":0,"isCheck":null,
              "Kinder":[]
            },
            {"id":"0CD6B09A-AA43-4AE9-9AC7-29BC5AC83495","pid":"0","code":"SJ","name":"Daten","path":"/data","type":null,"icon":null,"sysId":"2AB00274-73DF-459A-A02E-C79A4D8A8929","orderNo":0,"isCheck":null,
              "Kinder":[]
            },
            {"id":"049C670D-A33E-4188-9206-B3F3B5DDE77B","pid":"0","code":"SP","name":"Video","path":"/video","type":null,"icon":null,"sysId":"3691C2E8-8848-4439-8899-9A8039AE6AB5","orderNo":0,"isCheck":null,"children":[]},
            {"id":"0A15DBB6-3241-4C7F-AAD4-5417E7BBECAA","pid":"0","code":"RZ","name":"Log","path":"/log","type":null,"icon":null,"sysId":"2AB00274-73DF-459A-A02E-C79A4D8A8929","orderNo":0,"isCheck":null,
              "Kinder":[]
            }
          ]

Der Effekt ist wie unten dargestellt:

Bildbeschreibung hier einfügen

Nach dem Falten, wie gezeigt:

Bildbeschreibung hier einfügen

Dies ist das Ende dieses Artikels über die rekursive Implementierung der faltbaren dynamischen Rendering-Seitenleistennavigation mit mehreren Ebenen durch die Vue+ElementUI-Komponente. Weitere verwandte Inhalte zur faltbaren dynamischen Seitenleistennavigation von ElementUI 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 zur Verwendung der Navigationsleiste zum Springen zur Route in Element-UI
  • Ein Beispiel für die Verwendung von Vue-Router mit ElementUI zur Implementierung der Navigation
  • Lassen Sie uns über das Routerproblem der Element-UI-Seitenleiste sprechen

<<:  Dateifreigabe zwischen Ubuntu und Windows unter VMware

>>:  Lösung für 1067, wenn Mysql in Windows startet

Artikel empfehlen

So kapseln Sie die Tabellenkomponente von Vue Element

Beim Kapseln von Vue-Komponenten werde ich weiter...

Ausführliche Erläuterung der Mysql-Deadlock-Anzeige und Deadlock-Entfernung

Vorwort Vor einiger Zeit ist bei mir ein MySQL-De...

Transplantieren des Befehls mkfs.vfat in Busybox unter Linux

Um die Lebensdauer der Festplatte zum Speichern v...

Verwendung der MySQL DATE_FORMAT-Funktion

Angenommen, Taobao animiert die Leute zum Einkauf...

Lösen Sie das Problem der Groß- und Kleinschreibung der Linux+Apache-Server-URL

Ich bin heute auf ein Problem gestoßen. Beim Eing...

Bringen Sie Ihnen bei, wie Sie den Beobachtermodus in Javascript implementieren

Inhaltsverzeichnis Was ist das Beobachtermuster? ...

Implementierung der Docker-Bereitstellung des SQL Server 2019 Always On-Clusters

Inhaltsverzeichnis Docker-Bereitstellung Always o...

Implementierung eines Karussells mit nativem JavaScript

In diesem Artikel finden Sie den spezifischen Cod...

Lösen Sie das Problem beim Ausführen von Jupyter Notebook auf dem Server

Inhaltsverzeichnis Auf dem Server läuft Jupyter N...

Beispielcode zum Vergleich verschiedener Syntaxformate von vue3

Die Standardvorlagenmethode ähnelt vue2 und verwe...

MySQL-Sequenz AUTO_INCREMENT ausführliche Erklärung und Beispielcode

MySQL-Sequenz AUTO_INCREMENT ausführliche Erkläru...

Ausführliche Erläuterung der Standortpriorität von Nginx

Standortausdruckstyp ~ bedeutet, dass ein regulär...

CnBlogs - Teilen im benutzerdefinierten Blogstil

Nachdem ich die halbe Nacht daran gearbeitet hatt...