[Vue] Récursion des composants du framework Vue

récursivité des composants

Lorsque nous écrivons un module, parce que nous ne savons pas à quelle profondeur les données sont imbriquées, nous ne savons pas combien d'imbrications répétées il y a dans la structure des éléments du composant.Le modèle que nous utilisons actuellement est un modèle statique, nous le ferons donc. VueIl existe un phénomène qui ne peut pas exprimer pleinement la profondeur de nidification.

Par conséquent, dans ce scénario, le concept de récursivité des composants sera utilisé, ce qui signifie utiliser vos propres composants dans vos propres composants.

La clé est de faire attention

  • Nommer le composant (ajouter namedes attributs)
  • Les paramètres passés doivent également pouvoir terminer l'opération récursive et avoir une sortie récursive.
  • Lorsqu'il y a une inscription d'événement dans un composant, l'événement doit être enregistré pour le composant référencé.

Voici un exemple

Des scènes de niveaux imbriqués se produisent souvent, la plupart d'entre elles se trouvent donc au niveau du répertoire. Voici un Vueexemple de modèle au niveau du répertoire.

Supposons que nous voulions écrire un composant Catalogue.vuedont les données sont un Arraytableau de types qui lui est transmis par le composant parent. Sa dataconfiguration est la suivante

<script>
export default {
  name: "Catalogue",
  props: {
    /* 数据的结构简示
        [  
          { 
            name: "xxx", 
            isSelcet: false, 
          },
          { 
            name: "yyy", 
            isSelcet: false, 
            children: [
              {
                name: "zzz", 
                isSelect: true
              }
            ]
          }
        ]
    */
    list: {
      type: Array,
      // 如果要返回数组的话, 这里必须是一个函数,直接写数组是不行的
      default: () => [],
    },
  },
};
</script>

Ensuite, sur la base de ses données, nous pouvons savoir que sa structure de modèle peut être écrite sous la forme d'une liste. Le composant racine est un conteneur ul, et la liliste interne est liée à la quantité et à la profondeur des données. Par conséquent, nous pouvons d'abord listparcourir en fonction des attributs pour obtenir le modèle de couche le plus externe, comme indiqué dans le code suivant

<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>

Mais évidemment, cette façon d'écrire ne peut afficher qu'un seul calque. Si vous souhaitez afficher des composants avec une profondeur d'imbrication inconnue en fonction des listpropriétés children, vous devez effectuer une récursivité des composants en fonction des propriétés Vuede la configuration , comme indiqué dans le code suivant.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>

Cela équivaut à l'achèvement de la structure du modèle. Si cela implique l'enregistrement d'événements internes du composant, d'autres traitements d'enregistrement d'événements doivent être effectués, comme indiqué dans le code suivant.

Supposons que les éléments à l'intérieur du composant spandoivent enregistrer un événement de clic et que cet événement ne peut pas être géré dans ce composant. Un selectévénement doit être lancé vers l'élément parent, ce qui signifie le modèle et la configuration suivants :

<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>

Le problème ici est évident. Lors de l'exécution, seul le premier niveau d'imbrication spanenregistre les événements de clic, et les autres niveaux plus profonds spann'enregistrent pas les événements de clic. Vous devez ensuite apporter quelques modifications sur cette base pour que le composant enregistre de manière récursive l'** selectévénement**. encore une fois, le code est le suivant

<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>

selectLors de l'enregistrement d'un événement ici , il vous suffit de donner handlerClickun nom de fonction, car ce composant est équivalent à un sous-composant d'un sous-composant, il n'y a donc aucun moyen de traiter cette fonction et vous devez continuer à lancer des événements vers le haut. , afin que les paramètres selectet itemévénements Nom soient transmis au composant parent

Avis

Lors de l'enregistrement d'un événement pour un composant récursif, vous ne pouvez pas transmettre de paramètres itemcar il n'y a aucun moyen de itemle faire correspondre avec lui-même, vous n'avez donc besoin que du nom de la fonction, qui sera automatiquement apporté lors de l'utilisation des paramètres.

Je suppose que tu aimes

Origine blog.csdn.net/facial_123/article/details/126824979
conseillé
Classement