Passando adereços dinamicamente para o componente dinâmico no VueJS

105

Tenho uma visão dinâmica:

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

com uma instância Vue associada:

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

Isso me permite alterar meu componente dinamicamente.

No meu caso, eu tenho três componentes diferentes: myComponent, myComponent1, e myComponent2. E eu alterno entre eles assim:

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

Agora, eu gostaria de passar adereços para myComponent1.

Como posso passar esses adereços quando mudo o tipo de componente para myComponent1?

Epitouille
fonte
Você passa adereços por meio de atributos no elemento propName="propValue". Essa é a sua pergunta?
obrigado
Não posso porque nunca escrevo <myComponent1 propName="propValue">Eu mudo o componente programaticamente com$parent.currentComponent = componentName
Epitouille
Sim, mas você escreve <div :is="currentComponent"></div>. É onde você adicionaria o atributo.
obrigado
Sim, mas os adereços dependem do componente. Por exemplo, myComponent1pegue acessórios e myComponent2não pegue acessórios
Epitouille

Respostas:

213

Para passar props dinamicamente, você pode adicionar a v-binddiretiva ao seu componente dinâmico e passar um objeto contendo seus nomes e valores prop:

Portanto, seu componente dinâmico seria assim:

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

E em sua instância Vue, currentPropertiespode mudar com base no componente atual:

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

Portanto, agora, quando o currentComponentfor myComponent, ele terá uma foopropriedade igual a 'bar'. E quando não for, nenhuma propriedade será passada.

obrigado
fonte
Por que isso não está funcionando para mim? Ele funciona para o primeiro componente, mas depois de alterar o “currentComponent”, obtenho um “e.currentProperties” indefinido no componente filho.
Ricardo Vigatti
2
@RicardoVigatti, sem ver nada do seu código fica bem difícil saber
obrigado
Ei, se eu quiser adicionar algo no <component>(here)</component>. Isso é possível?
Felipe Morales
1
@FelipeMorales, sim, você só precisa definir um padrão <slot>para cada componente que estiver renderizando dinamicamente. vuejs.org/v2/guide/components-slots.html
obrigado
1
O guia de estilo diz que os nomes dos prop devem ser tão detalhados quanto possível. Assim, quebra a regra. Isso também é o que eu uso, mas estou procurando uma solução melhor.
Koray Küpe
8

Você também pode fazer sem propriedade computada e embutir o objeto.

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

Mostrado na documentação do V-Bind - https://vuejs.org/v2/api/#v-bind

Jquestions
fonte
2

Você poderia construí-lo como ...

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ó
fonte
1

Se você importou seu código por meio de require

var patientDetailsEdit = require('../patient-profile/patient-profile-personal-details-edit')
e inicializar a instância de dados como abaixo

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

você também pode fazer referência ao componente por meio da propriedade de nome se seu componente o tiver atribuído

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

Mark Dowton
fonte