recursividad de componentes
Cuando escribimos un módulo, debido a que no sabemos qué tan profundamente están anidados los datos, no sabemos cuántos anidamientos repetidos hay en la estructura de elementos del componente. La plantilla que usamos en este momento es una plantilla estática, Entonces lo Vue
haremos. Hay un fenómeno que no puede expresar completamente la profundidad de anidación.
Por lo tanto, en este escenario, se utilizará el concepto de recursividad de componentes, lo que significa utilizar sus propios componentes en sus propios componentes.
La clave es prestar atención.
- Nombra el componente (agrega
name
atributos) - Los parámetros pasados también deben poder completar la operación recursiva y tener una salida recursiva.
- Cuando hay un registro de evento en un componente, el evento debe registrarse para el componente referenciado.
Aquí hay un ejemplo
A menudo se producen escenas de niveles anidados, por lo que la mayoría de ellas están en el nivel de directorio. El siguiente es un Vue
ejemplo de una plantilla de nivel de directorio.
Supongamos que queremos escribir un componente Catalogue.vue
cuyos datos sean una Array
matriz de tipos que le pasa el componente principal, su data
configuración es la siguiente
<script>
export default {
name: "Catalogue",
props: {
/* 数据的结构简示
[
{
name: "xxx",
isSelcet: false,
},
{
name: "yyy",
isSelcet: false,
children: [
{
name: "zzz",
isSelect: true
}
]
}
]
*/
list: {
type: Array,
// 如果要返回数组的话, 这里必须是一个函数,直接写数组是不行的
default: () => [],
},
},
};
</script>
Luego, según sus datos, podemos saber que su estructura de plantilla se puede escribir en forma de lista. El componente raíz es un contenedor ul
y la li
lista interna está relacionada con la cantidad y profundidad de los datos. Por lo tanto, primero podemos list
recorra de acuerdo con los atributos para obtener la plantilla de capa más externa, como se muestra en el siguiente código
<template>
<ul class="catalogue-container">
<li v-for="(item, i) in list" :key="i">
<span :class="{'active': item.isSelect}"> {
{ item.name }} </span>
</li>
</ul>
</template>
Pero obviamente, esta forma de escribir solo puede mostrar una capa. Si desea mostrar componentes con profundidad de anidamiento desconocida según list
las propiedades children
, debe realizar la recursividad del componente según las propiedades Vue
en la configuración , como se muestra en el siguiente código.name
<template>
<ul class="catalogue-container">
<li v-for="(item, i) in list" :key="i">
<span :class="{'active': item.isSelect}"> {
{ item.name }} </span>
/* 进行组件递归,知道item.children为空 */
<Catalogue :list="item.children">
</li>
</ul>
</template>
Esto equivale a completar la estructura de la plantilla. Si implica el registro de eventos internos del componente, se debe realizar otro procesamiento de registro de eventos, como se muestra en el siguiente código.
Supongamos que los elementos dentro del componente span
necesitan registrar un evento de clic, y este evento no se puede manejar en este componente. select
Es necesario lanzar un evento al elemento principal, lo que significa la siguiente plantilla y configuración:
<template>
<ul class="catalogue-container">
<li v-for="(item, i) in list" :key="i">
<span
:class="{'active': item.isSelect}"
@click="handlerClick(item)"
> {
{ item.name }} </span>
/* 进行组件递归,知道item.children为空 */
<Catalogue :list="item.children">
</li>
</ul>
</template>
<script>
export default {
methods: {
handlerClick(item) {
console.log("Catalogue", item);
this.$emit("select", item);
},
},
};
</script>
El problema aquí es obvio. Cuando se ejecuta, solo el primer nivel de anidamiento span
registra eventos de clic, y otros niveles más profundos span
no registran eventos de clic. Luego, debe realizar algunas modificaciones sobre esta base para que el componente registre recursivamente el ** select
evento ** De nuevo, el código es el siguiente.
<template>
<ul class="catalogue-container">
<li v-for="(item, i) in list" :key="i">
<span
:class="{'active': item.isSelect}"
@click="handlerClick(item)"
> {
{ item.name }} </span>
<Catalogue
:list="item.children"
@select="handlerClick"
>
</li>
</ul>
</template>
<script>
export default {
methods: {
handlerClick(item) {
console.log("Catalogue", item);
this.$emit("select", item);
},
},
};
</script>
select
Al registrar un evento aquí , solo necesita proporcionar un handlerClick
nombre de función, porque este componente es equivalente a un subcomponente de un subcomponente, por lo que no hay forma de procesar esta función y debe continuar lanzando eventos hacia arriba. , para que los parámetros select
y item
eventos Nombre pasen al componente principal
Aviso
Al registrar un evento para un componente recursivo, no puede pasar parámetros item
porque no hay forma de hacer item
coincidirlo consigo mismo, por lo que solo necesita el nombre de la función, que se mostrará automáticamente cuando use parámetros.