Passer des accessoires dynamiquement au composant dynamique dans VueJS

105

J'ai une vue dynamique:

<div id="myview">
  <div :is="currentComponent"></div>
</div>

avec une instance Vue associée:

new Vue ({
  data: function () {
    return {
      currentComponent: 'myComponent',
    }
  },
}).$mount('#myview');

Cela me permet de changer mon composant de manière dynamique.

Dans mon cas, j'ai trois composantes différentes: myComponent, myComponent1et myComponent2. Et je passe de l'un à l'autre comme ceci:

Vue.component('myComponent', {
  template: "<button @click=\"$parent.currentComponent = 'myComponent1'\"></button>"
}

Maintenant, j'aimerais passer des accessoires à myComponent1.

Comment puis-je transmettre ces accessoires lorsque je change le type de composant en myComponent1?

Épitouille
la source
Vous passez des accessoires via des attributs sur l'élément propName="propValue". C'est ta question?
merci
Je ne peux pas car je <myComponent1 propName="propValue">$parent.currentComponent = componentName
n'écris
Ouais mais tu écris <div :is="currentComponent"></div>. C'est là que vous ajouteriez l'attribut.
merci
Oui, mais les accessoires dépendent du composant. Par exemple, myComponent1prenez les accessoires et myComponent2ne prenez pas les accessoires
Epitouille

Réponses:

214

Pour passer des accessoires dynamiquement, vous pouvez ajouter la v-binddirective à votre composant dynamique et passer un objet contenant vos noms et valeurs d'accessoires:

Ainsi, votre composant dynamique ressemblerait à ceci:

<component :is="currentComponent" v-bind="currentProperties"></component>

Et dans votre instance Vue, currentPropertiespeut changer en fonction du composant actuel:

data: function () {
  return {
    currentComponent: 'myComponent',
  }
},
computed: {
  currentProperties: function() {
    if (this.currentComponent === 'myComponent') {
      return { foo: 'bar' }
    }
  }
}   

Alors maintenant, quand le currentComponentest myComponent, il aura une foopropriété égale à 'bar'. Et quand ce n'est pas le cas, aucune propriété ne sera transmise.

merci: D
la source
Pourquoi cela ne fonctionne pas pour moi? Cela fonctionne pour le premier composant, mais après avoir changé le «currentComponent», j'obtiens un «e.currentProperties» qui n'est pas défini sur le composant enfant.
Ricardo Vigatti
2
@RicardoVigatti, sans voir aucun de votre code, c'est assez difficile à savoir
merci
Hé, si je veux ajouter quelque chose <component>(here)</component>. C'est possible?
Felipe Morales
1
@FelipeMorales, oui, il vous suffit de définir une valeur <slot>par défaut pour chaque composant que vous rendez dynamiquement. vuejs.org/v2/guide/components-slots.html
merci le
1
Le guide de style indique que les noms d'accessoires doivent être aussi détaillés que possible. Cette façon enfreint la règle. C'est aussi ce que j'utilise, mais je recherche une meilleure solution.
Koray Küpe
8

Vous pouvez également vous passer de la propriété calculée et intégrer l'objet.

<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>

Montré dans la documentation sur V-Bind - https://vuejs.org/v2/api/#v-bind

Jquestions
la source
2

Vous pouvez le construire comme ...

comp: { component: 'ComponentName', props: { square: true, outlined: true, dense: true }, model: 'form.bar' }
     
<component :is="comp.component" v-bind="{...comp.props}" v-model="comp.model"/>

Kornél Takó
la source
1

Si vous avez importé votre code via require

var patientDetailsEdit = require('../patient-profile/patient-profile-personal-details-edit')
et initialisez l'instance de données comme ci-dessous

data: function () {
            return {
                currentView: patientDetailsEdit,
            }

vous pouvez également référencer le composant via la propriété name si vous l'avez attribué au composant

currentProperties: function() {
                if (this.currentView.name === 'Personal-Details-Edit') {
                    return { mode: 'create' }
                }
            }

Mark Dowton
la source