Pasando accesorios dinámicamente al componente dinámico en VueJS

105

Tengo una vista dinámica:

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

con una instancia de Vue asociada:

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

Esto me permite cambiar mi componente de forma dinámica.

En mi caso, tengo tres componentes diferentes: myComponent, myComponent1, y myComponent2. Y cambio entre ellos así:

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

Ahora, me gustaría pasarle accesorios myComponent1.

¿Cómo puedo pasar estos accesorios cuando cambio el tipo de componente a myComponent1?

Epitouille
fuente
Pasas accesorios a través de atributos en el elemento propName="propValue". ¿Esa es tu pregunta?
agradecido el
No puedo porque nunca escribo <myComponent1 propName="propValue">, cambio el componente mediante programación con$parent.currentComponent = componentName
Epitouille
Sí, pero escribe <div :is="currentComponent"></div>. Ahí es donde agregarías el atributo.
agradecido el
Sí, pero los accesorios dependen del componente. Por ejemplo, myComponent1toma accesorios y myComponent2no acepta accesorios
Epitouille

Respuestas:

213

Para pasar props dinámicamente, puede agregar la v-binddirectiva a su componente dinámico y pasar un objeto que contenga sus nombres y valores de prop:

Entonces, su componente dinámico se vería así:

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

Y en su instancia de Vue, currentPropertiespuede cambiar según el componente actual:

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

Así que ahora, cuando currentComponentsea myComponent, tendrá una foopropiedad igual a 'bar'. Y cuando no lo sea, no se transferirán propiedades.

gracias: D
fuente
¿Por qué esto no me funciona? Funciona para el primer componente, pero después de cambiar el "currentComponent" obtengo un "e.currentProperties" no está definido en el componente hijo.
Ricardo Vigatti
2
@RicardoVigatti, sin ver nada de su código, es bastante difícil de saber
gracias
Oye, si quiero agregar algo <component>(here)</component>. ¿Es eso posible?
Felipe Morales
1
@FelipeMorales, sí, solo necesitaría definir un valor predeterminado <slot>para cada componente que está renderizando dinámicamente. vuejs.org/v2/guide/components-slots.html
gracias,
1
La guía de estilo dice que los nombres de los accesorios deben ser lo más detallados posible. De esta manera rompe la regla. Esto también es lo que uso, pero estoy buscando una mejor solución.
Koray Küpe
8

También puede prescindir de la propiedad calculada e insertar el objeto en línea.

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

Se muestra en los documentos de V-Bind: https://vuejs.org/v2/api/#v-bind

Jpreguntas
fuente
2

Podrías construirlo 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ó
fuente
1

Si ha importado su código a través de require

var patientDetailsEdit = require('../patient-profile/patient-profile-personal-details-edit')
e inicialice la instancia de datos como se muestra a continuación

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

también puede hacer referencia al componente a través de la propiedad name si su componente lo tiene asignado

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

Mark Dowton
fuente