recherche

Maison  >  Questions et réponses  >  le corps du texte

Existe-t-il un moyen de déclarer la fourniture/injection dans un composant dynamique Vue3 en dehors de la fonction de paramètres de l'hôte ?

<p>Je crée un <code>Composant dynamique</code> dans <code>Vue3</code>. J'utilise <code>v-bind</code> pour fournir <code>props</code>. </p> <pre class="lang-js Prettyprint-override"><code><component :is='MyComponent' v-bind='myProps' /> </code></pre> <p>Je souhaite fournir/injecter</code> une fonctionnalité à l'aide de <code>. Comment puis-je mettre les propriétés que je fournis dans le composant dynamique. Mon composant dynamique appelle <code>inject</code> dans la fonction <code>setup</code> et attend une valeur </code> </p> <p>Bien que cela ne soit pas documenté sur Vue, je l'ai essayé sans succès : </p> <pre class="brush:php;toolbar:false;"><component :is='MyComponent' v-bind='myProps' :provide='myProvidedProps'/></pre> <p> J'ai même essayé de placer l'objet <code>provide</code> dans l'objet <code>props</code> </p>
P粉384366923P粉384366923452 Il y a quelques jours501

répondre à tous(1)je répondrai

  • P粉122932466

    P粉1229324662023-08-31 00:50:39

    Après avoir parcouru le code source de Vue3, vous ne pouvez pas le 动态组件指示providespécifier directement dans le modèle. Il doit être appelé dans les paramètres de fonction ou d'options du parent hébergeant le composant dynamique, ou dans les paramètres ou options du composant dynamique.

    Les deux options sont :

    1. Vous faites appel à provide sur le composant qui héberge le composant dynamique.
    setup() {
      provide('message', 'hello')
    }
    <template>
      <component :is='myComponent' />
    </template>

    Cela ne fonctionne pas pour moi car ma fonction setter est appelée avant que mon composant dynamique ne soit activé ; j'ai également besoin que le type de composant soit défini avec la valeur fournie.

    1. Envoyez les éléments à fournir comme accessoires dans le composant et laissez le composant dynamique les appeler.
    function setComponent(someImportedComponent, providedValues) {
      myComponent.value = someImportedComponent
      myProps.value = {
        toProvide: providedValues
      }
    }
    <template>
      <component :is='myComponent' v-bind='myProps' />
    </template>

    Mes composants

    setup() {
      for(let [key,value] of Object.entries(props.toProvide) ) {
        provide(key, value)
      }
    }

    Maintenant, cela a ses problèmes, car chaque composant dynamique doit désormais être responsable de la compréhension et de l'appel du fournisseur entrant.

    Solution 1

    La solution pour que chaque composant ait besoin de connaître la valeur fournie est de créer un composant intermédiaire qui fournit la valeur.

    Disponible (composants intermédiaires)

    <script setup lang="ts">
    import {provide} from 'vue'
    
    const props = defineProps<{
      is: any
      provide?: Record<string, any>
      [key: string]: any
    }>()
    
    if (props.provide) {
      for (const [key, value] of Object.entries(props.provide)) {
        provide(key, value)
      }
    }
    
    const _props = Object.fromEntries(Object.entries(props).filter(it => {
      return it[0] !== 'is' && it[0] !== 'provide'
    }))
    </script>
    
    <template>
      <component :is="is" v-bind="_props"/>
    </template>

    Utilisez-le comme ceci :

    <template>
      <providable :is="myComponent" :provide='toProvide' v-bind='myProps' />
    </template>

    Solution 2

    Une solution plus propre consiste à créer un composant wrapper, similaire au fonctionnement de keep-alive. Il suffit de mettre le composant cible 默认槽.

    fourni.vue

    <script setup lang="ts">
    import {provide} from 'vue'
    
    const props = defineProps<{
      value: Record<string, any>
    }>()
    
    for (const [key, value] of Object.entries(props.value)) {
      provide(key, value)
    }
    </script>
    
    <template>
      <slot name="default"/>
    </template>

    et utilisez-le comme ceci :

    <template>
      <provide value='toProvide'>
        <my-component v-bind='myProps' />
      </provide>
    </template>

    répondre
    0
  • Annulerrépondre