[Vue] Recurrencia de componentes del marco Vue

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 Vueharemos. 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 nameatributos)
  • 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 Vueejemplo de una plantilla de nivel de directorio.

Supongamos que queremos escribir un componente Catalogue.vuecuyos datos sean una Arraymatriz de tipos que le pasa el componente principal, su dataconfiguració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 uly la lilista interna está relacionada con la cantidad y profundidad de los datos. Por lo tanto, primero podemos listrecorra 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 listlas propiedades children, debe realizar la recursividad del componente según las propiedades Vueen 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 spannecesitan registrar un evento de clic, y este evento no se puede manejar en este componente. selectEs 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 spanregistra eventos de clic, y otros niveles más profundos spanno registran eventos de clic. Luego, debe realizar algunas modificaciones sobre esta base para que el componente registre recursivamente el ** selectevento ** 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>

selectAl registrar un evento aquí , solo necesita proporcionar un handlerClicknombre 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 selecty itemeventos Nombre pasen al componente principal

Aviso

Al registrar un evento para un componente recursivo, no puede pasar parámetros itemporque no hay forma de hacer itemcoincidirlo consigo mismo, por lo que solo necesita el nombre de la función, que se mostrará automáticamente cuando use parámetros.

Supongo que te gusta

Origin blog.csdn.net/facial_123/article/details/126824979
Recomendado
Clasificación