English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In Vue.js, un componente ricorsivo chiama se stesso, come:
Vue.component('recursive-component', { template: `<!--Chiamandomi stesso!--> <recursive-component></recursive-component> });
I componenti ricorsivi sono spesso utilizzati per visualizzare commenti, menu嵌套, o fondamentalmente tipi di padre e figlio identici, anche se i contenuti specifici differiscono. Ad esempio:
Ora vi dimostrerò come utilizzare efficacemente i componenti ricorsivi, passo dopo passo creando un menu a albero espandibile/comprimibile.
Struttura dati
Un componente UI ad albero ricorsivo sarà una rappresentazione visiva di una struttura dati ricorsiva. In questo tutorial, utilizzeremo una struttura ad albero in cui ogni nodo è un oggetto:
Un attributo label.
Se ha figli, un attributo nodes, è un array di uno o più nodi.
Come tutte le strutture ad albero, deve avere un nodo radice, ma può essere infinitamente profonda.
let tree = { label: 'root', nodes: [ { label: 'item1', nodes: [ { label: 'item1.1' }, { label: 'item1.2', nodes: [ { label: 'item1.2.1' } ] } ] }, { label: 'item2' } ] }
Componente ricorsivo
Facciamo un componente ricorsivo per visualizzare la nostra struttura dati chiamata TreeMenu. Mostra solo l'etichetta del nodo corrente e si chiama a se stesso per visualizzare qualsiasi nodo figlio. Il nome del file è TreeMenu.vue, il contenuto è il seguente:
<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>
Se utilizzi un componente ricorsivo, devi prima fare una definizione globale di Vue.component, o dargli un attributo name. Altrimenti, qualsiasi componente figlio non potrà chiamarlo ulteriormente e riceverai un messaggio di errore "undefined component" incerto.
Evento di base
Come qualsiasi funzione ricorsiva, hai bisogno di un evento di base per fermare la ricorsione, altrimenti il rendering continuerà indefinitamente e alla fine causerà un overflow di stack.
Nel menu a albero, quando raggiungiamo un nodo senza figli, vogliamo fermare la ricorsione. Puoi farlo con v-if, ma abbiamo scelto di utilizzare v-for che lo farà implicitamente per noi; se l'array nodes non ha ulteriori definizioni, il componente tree-menu verrà chiamato. Il file template.vue è il seguente:
<template> <div class="tree-menu"> ... <!--Se `nodes` è undefined, questo non verrà renderizzato--> <tree-menu v-for="node in nodes"></tree-menu> </template>
Uso
Come possiamo utilizzare questo componente? Prima di tutto, dichiariamo un'istanza Vue con una struttura dati che include l'attributo data e il componente definito treemenu. Il file app.js è il seguente:
import TreeMenu from './TreeMenu.vue' let tree = { ... } new Vue({ el: '#app', data: { tree }, components: { TreeMenu } )
Ricorda che la nostra struttura dei dati ha un nodo radice. Nell'inizio del template principale chiamiamo ricorsivamente il componente TreeMenu, utilizzando l'attributo nodes radice come props:
<div id="app"> <tree-menu :label="tree.label" :nodes="tree.nodes"></tree-menu> </div>
Ecco come appare al momento:
Postura corretta
È utile riconoscere visivamente la "profondità" del componente figlio, in modo che l'utente possa ottenere una sensazione della struttura dei dati dall'UI. Facciamo rientrare ogni livello di nodi figlio per raggiungere questo obiettivo.
È fatto aumentando un prop depth, implementato tramite TreeMenu. Utilizzeremo questo valore per associare dinamicamente lo stile inline con i vincoli di trasformazione: utilizzeremo la regola CSS transform: translate per ogni etichetta del nodo, creando un rientro. Le modifiche al file template.vue sono come segue**:**
<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>
L'attributo depth parte da zero nel template principale. Nel template del componente, puoi vedere che questo valore aumenta ogni volta che viene passato a qualsiasi nodo figlio.
<div id="app"> <tree-menu :label="tree.label" :nodes="tree.nodes" :depth="0" </tree-menu> </div>
Attenzione: ricorda di usare v-bind per il valore depth per assicurarti che sia un tipo di numero JavaScript e non una stringa.
Espandere/Ripiegare
Poiché la struttura dei dati ricorsiva può essere molto grande, un ottimo trucco per la visualizzazione è nascondere tutti i nodi tranne il nodo radice, in modo che l'utente possa espandere o ripiegare i nodi come necessario.
Per questo, aggiungeremo una proprietà locale showChildren. Se il suo valore è False, i nodi figli non verranno visualizzati. Questo valore deve essere modificato tramite il clic sul nodo, quindi dobbiamo utilizzare un metodo di ascolto degli eventi di clic toggleChildren per la gestione. Le modifiche al file template.vue sono come segue**:**
<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>
Conclusione
In questo modo, abbiamo un menu ad albero funzionante. Un metodo per aggiungere il tocco finale è quello di aggiungere un'icona di aggiunta/rimozione, il che rende la visualizzazione dell'UI più evidente. Ho anche migliorato il font e le prestazioni di calcolo rispetto a showChildren.
Dichiarazione: il contenuto di questo articolo è stato tratto da Internet, di proprietà del rispettivo autore, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, il sito web non detiene i diritti di proprietà, non è stato editato manualmente e non assume alcuna responsabilità legale. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a notice#oldtoolbag.com (sostituisci # con @) per segnalare il problema, fornendo prove pertinenti. Una volta verificata la veridicità, il sito web rimuoverà immediatamente i contenuti sospetti di violazione del copyright.