web-dev-qa-db-fra.com

Est-il possible de passer un composant comme accessoire et de l'utiliser dans un composant enfant dans Vue?

Dans une application Vue 2.0, supposons que nous ayons les composants A, B et C.

A déclare, enregistre et utilise B

Est-il possible de passer C de A à B?

Quelque chose comme ça:

<template>
  <div class="A">
    <B :child_component="C" />
  </div>
</template>

Et utilisez C en B d'une manière ou d'une autre.

<template>
  <div class="B">
    <C>Something else</C>
  </div>
</template>

La motivation: je veux créer un composant générique B qui est utilisé dans A mais reçoit de A son enfant C. En fait, A utilisera B plusieurs fois en lui transmettant différents C.

Si cette approche n'est pas correcte, quelle est la bonne façon de le faire dans Vue?

Répondant à @Saurabh

Au lieu de passer pour des accessoires, j'ai essayé la suggestion à l'intérieur de B.

<!-- this is where I Call the dynamic component in B -->

<component :is="child_component"></component>

//this is what I did in B js
components: {
 equip: Equipment
}, 
data () {
 return {
   child_component: 'equip',
   _list: []
 }
}

Fondamentalement, j'essaie de rendre l'équipement, mais de manière dynamique

Je reçois 3 erreurs en console et une page blanche

[Vue warn]: Erreur lors du rendu du composant dans /home/victor/projetos/tokaai/public/src/components/EquipmentFormItem.vue:

Uncaught TypeError: Impossible de lire la propriété 'nom' de non défini

TypeError: Impossible de lire la propriété 'setAttribute' de non définie

Apparemment je fais quelque chose de mal

34
Victor Ferreira

Vous pouvez utiliser l'attribut spécial is pour faire ce genre de chose. Exemple de composant dynamique et son utilisation peuvent être trouvés ici .

Vous pouvez utiliser le même point de montage et basculer de manière dynamique entre plusieurs composants à l'aide de l'élément réservé et se lier dynamiquement à son attribut is:

Votre code ressemblera à ceci:

<template>
  <div class="B">
    <component :is="child_component"> Something else</component>
  </div>
</template>
16
Saurabh

En résumé:

<!-- Component A -->
<template>
  <div class="A">
    <B>
      <component :is="child_component"></component>
    </B>
  </div>
</template>

<script>
import B from './B.vue';
import Equipment from './Equipment.vue';

export default {
  name: 'A',
  components: { B, Equipment },
  data() {
    return { child_component: 'equipment' };
  }
};
</script>

<!-- Component B -->
<template>
  <div class="B">
    <h1>Some content</h1>
    <slot></slot> <!-- Component C will appear here -->
  </div>
</template>
16
Jonatas Walker

Voici la solution pour transférer un composant personnalisé via les accessoires d'un autre composant

:is est un attribut spécial qui sera utilisé pour remplacer votre composant actuel et sera ignoré si vous essayez de l’utiliser comme accessoire dans votre composant. Heureusement, vous pouvez utiliser quelque chose d'autre comme el puis l'envoyer à component comme ceci:

<template>
  <div>
    <component :is="el">
      <slot />
    </component>
  </div>
</template>
<script>
  export default {
    name: 'RenderDynamicChild',
    props: {
        el: {
            type: [String, Object],
            default: 'div',
        },
    },
  }
</script>

Tout élément valide que vous utilisez dans l'attribut el sera utilisé en tant que composant enfant. Il peut s'agir de HTML ou d'une référence à votre composant personnalisé ou de div par défaut, comme spécifié dans la déclaration du composant.

Passer un composant personnalisé à l'hélice est un peu délicat. On pourrait supposer que vous déclarez dans une propriété components du composant parent et l’utilisez ensuite pour l’attribut el, mais cela ne fonctionne pas. Au lieu de cela, vous devez avoir votre composant dynamique dans la propriété data ou computed pour pouvoir l'utiliser dans un modèle en tant que prop. Notez également que AnotherComponent n'a pas besoin d'être déclaré dans la propriété components.

<template>
  <RenderDynamicChild :el="DynamicComponent">
    Hello Vue!
  </RenderDynamicChild>
</template>

<script>
import RenderDynamicChild from './DynamicChild';
import AnotherComponent from './AnotherComponent';

export default {
  name: "ParentComponent",
  components: { DynamicChild },
  data() {
    return {
      DynamicComponent: AnotherComponent,
    };
  },
};
</script>

L'utilisation de la propriété calculée pour votre composant dynamique vous permet de basculer facilement entre les composants:

<script>
import DynamicChild from './DynamicChild';
import AnotherComponent from './AnotherComponent';

export default {
  name: "ParentComponent",
  components: { DynamicChild },
  data() { return { count: 0 } },
  computed: {
    DynamicComponent() {
      return this.count % 2 > 1 ? AnotherComponent : 'article';
    },
  },
};
</script>

Augmenter this.count pour alterner entre AnotherComponent et un élément simple article html.

1
NiBi