English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In Vue.js wird eine rekursive Komponente auf sich selbst aufgerufen, wie z.B.:
Vue.component('recursive-component', { template: `<!--Invoking myself!--> <recursive-component></recursive-component>` });
Rekursive Komponenten werden oft verwendet, um Kommentare in Blogs anzuzeigen, eingebettete Menüs oder im Allgemeinen Typen, die gleiche Eltern- und Kind-Typen haben, obwohl der spezifische Inhalt unterschiedlich ist. Zum Beispiel:
Nun zeige ich Ihnen, wie Sie rekursive Komponenten effektiv verwenden können. Ich werde einen erweiterbaren/Wir werden Schritt für Schritt einen zusammengeklappten Baummenü durchgehen.
Datenstruktur
Ein rekursiver UI-Baumkomponente ist eine visuelle Darstellung von rekursiven Datenstrukturen. In diesem Tutorial verwenden wir eine Baumstruktur, bei der jeder Knoten ein Objekt ist:
Ein label-Attribut.
Wenn sie Unter knots hat und eine nodes-Attribut, dann ist es ein oder mehrere Knoten-Arrays.
Wie jede Baumstruktur muss sie einen Wurzelknoten haben, aber sie kann unendlich tief sein.
let tree = { label: 'root', nodes: [ { label: 'item'1', nodes: [ { label: 'item'1.1' }, { label: 'item'1.2', nodes: [ { label: 'item'1.2.1' } ] } ] }, { label: 'item'2' } ] }
Rekursive Komponente
Lassen Sie uns eine rekursive Komponente machen, um unsere Datenstruktur TreeMenu anzuzeigen. Sie zeigt nur das Label des aktuellen Knotens und ruft sich selbst auf, um alle Unter knots anzuzeigen. Dateiname: TreeMenu.vue, Inhalt wie folgt:
<template> <div class="tree-menu"> <div>{{ label }}</div> <tree-menu v-for="node in nodes" :nodes="node.nodes" :label="node.label" > </tree-menu> </div> </template> <script> export default { props: [ 'label', 'nodes' ], name: 'tree-menu' } </script>
Wenn du eine komponente rekursiv verwendest, musst du Vue.component eine globale Definition geben oder ihr einen Namen zugeordnet.
Basisevent
Wie jede rekursive Funktion musst du ein Basisevent haben, um die Rekursion zu beenden, andernfalls wird das Rendern unendlich fortgesetzt und führt letztlich zu einem Stack Overflow.
Im Baummenü, wenn wir einen Knoten erreichen, der keine Unter knots hat, möchten wir die Rekursion stoppen. Du kannst dies durch v-wäre dies mit if möglich, aber wir entscheiden uns für die Verwendung von v-for wird implizit für uns implementiert; wenn die nodes-Array keine weitere Definition des trees enthält-Das menu-Component wird aufgerufen. Die Datei template.vue sieht wie folgt aus:
<template> <div class="tree-menu"> ... <!--Wenn `nodes` nicht definiert ist, wird dies nicht gerendert--> <tree-menu v-for="node in nodes"></tree-menu> </template>
Verwendung
Wie verwenden wir diesen Komponenten? Zunächst erklären wir eine Vue-Instanz, die eine Datenstruktur mit dem Attribut data und dem definierten treemenu-Komponenten enthält. Der app.js-Datei ist wie folgt:
import TreeMenu from '.'/TreeMenu.vue let tree = { ... } new Vue({ el: '#app', data: { tree }, components: { TreeMenu } )
Denken Sie daran, dass unsere Datenstruktur einen Wurzelknoten hat. Wir rufen den TreeMenu-Komponenten in der Hauptvorlage rekursiv auf, indem wir die Wurzel nodes-Eigenschaft als props verwenden:
<div id="app"> <tree-menu :label="tree.label" :nodes="tree.nodes"></tree-menu> </div>
Hier ist es derzeit:
Richtige Haltung
Es ist gut, die "Tiefe" des Unterkomponenten visuell zu erkennen, damit der Benutzer ein Gefühl für die Datenstruktur aus der UI erhält. Lassen Sie uns jeden Unter knoten der Ebene einklappen, um dieses Ziel zu erreichen.
Dies wird durch Hinzufügen eines depth props definiert, um dies durch TreeMenu zu erreichen. Wir verwenden diesen Wert, um die Inline-Styles dynamisch mit dem Binding zu verknüpfen: wir verwenden die CSS-Regel transform: translate für jede Knotenbezeichnung, um den Einzug zu erstellen. Die Änderung des template.vue ist wie folgt:**:}}**
<template> <div class="tree-menu"> <div :style="indent">{{ label }}</div> <tree-menu v-for="node in nodes" :nodes="node.nodes" :label="node.label" :depth="depth + 1" > </tree-menu> </div> </template> <script> export default { props: [ 'label', 'nodes', 'depth' ], name: 'tree-menu', computed: { indent() { return { transform: `translate(${this.depth * 50}px)` } } } } </script>
Die depth-Eigenschaft beginnt im Haupttemplate mit Null. In der obigen Komponentenvorlage können Sie sehen, dass dieser Wert bei jedem Übergeben an einen beliebigen Unter knoten zunimmt.
<div id="app"> <tree-menu :label="tree.label" :nodes="tree.nodes" :depth="0" ></tree-menu> </div>
Beachten Sie: Erinnern Sie sich an v-bind depth-Wert, um sicherzustellen, dass es sich um einen JavaScript-Nummerntyp und nicht um einen String handelt.
Ausklappen/Einklappen
Da rekursiv aufbauende Datenstrukturen sehr groß sein können, ist es eine gute UI-Technik, außer dem Wurzelknoten alle Knoten zu verbergen, damit der Benutzer die Knoten nach Bedarf ein- oder ausklappen kann.
Daher werden wir eine lokale Eigenschaft showChildren hinzufügen. Wenn sein Wert False ist, werden die Kindknoten nicht gerendert. Dieser Wert sollte durch Klicken auf den Knoten umgeschaltet werden, daher müssen wir einen Einmalklick-Event-Listener-Methode toggleChildren verwenden, um dies zu verwalten. Die Änderung des template.vue-Datei ist wie folgt:**:}}**
<template> <div class="tree-menu"> <div :style="indent" @click="toggleChildren">{{ label }}</div> <tree-menu v-if="showChildren" v-for="node in nodes" :nodes="node.nodes" :label="node.label" :depth="depth + 1" > </tree-menu> </div> </template> <script> export default { props: [ 'label', 'nodes', 'depth' ], data() { return { showChildren: false } }, name: 'tree-menu', computed: { indent() { return { transform: `translate(${this.depth * 50}px)` } } }, methods: { toggleChildren() { this.showChildren = !this.showChildren; } } } </script>
Zusammenfassung
So haben wir ein funktionierendes Baummenü. Eine Methode, um es zu verfeinern, ist, dass Sie ein Pluszeichen hinzufügen können/Minus-Symbol, das die Anzeige der UI deutlicher macht. Ich habe auch sehr gute Schriftarten und Berechnungsleistung hinzugefügt, basierend auf showChildren.
Besuchen Sie CodePen ( https://codepen.io/anthonygore/pen/PJKNqaSchauen Sie sich an, wie ich es umgesetzt habe.