Contexto

En Vue 2.0 la documentación y otros indican claramente que la comunicación de padre a hijo que pasa a través de los accesorios.

Pregunta

¿Cómo puede un padre decirle a su hijo un evento que ha sucedido a través de props?

Debe acabo de ver una proposición evento llamado? Que no se siente bien, ni alternativas ($emit/$on es para niño con el padre, y un centro modelo para distantes de los elementos).

Ejemplo

Tengo un contenedor primario y necesita decirle a su hijo contenedor que está bien participar a ciertas acciones a través de un API. Necesito para ser capaz de activar las funciones.

InformationsquelleAutor jbodily | 2017-03-06

9 Comentarios

  1. 138

    Dar al niño un componente ref y uso $refs llamar a un método en el componente hijo directamente.

    html:

    <div id="app">
      <child-component ref="childComponent"></child-component>
      <button @click="click">Click</button>  
    </div>

    javascript:

    var ChildComponent = {
      template: '<div>{{value}}</div>',
      data: function () {
        return {
          value: 0
        };
      },
      methods: {
        setValue: function(value) {
            this.value = value;
        }
      }
    }
    
    new Vue({
      el: '#app',
      components: {
        'child-component': ChildComponent
      },
      methods: {
        click: function() {
            this.$refs.childComponent.setValue(2.0);
        }
      }
    })

    Para obtener más información, consulte Vue documentación en refs.

    • De esta manera los padres y el niño componentes se acoplan. Para los eventos reales, por ejemplo cuando usted no sólo puede cambiar una proposición para desencadenar una acción, me gustaría ir con el autobús de la solución sugerida por @Roy J
    • ref a la documentación sería un útil aswell vuejs.org/v2/guide/…
    • En mi hijo componente, por razones especiales, he tenido que utilizar v-una vez para terminar la reactividad. Lo que pasa que la proposición de padre a hijo no era una opción, así que esta solución se hizo el truco!
    • novato pregunta: ¿por Qué utilizar ref en lugar de la creación de una proposición, de que los relojes de su valor luego de emitirlo a otra función en el padre? me refiero a que no tiene un montón de cosas que hacer, pero que está utilizando ref incluso seguro? Gracias
    • sí, ref es seguro. Por lo general, es desanimado porque la Vue de la comunidad prefiere pasar del estado a los niños, y los acontecimientos de vuelta al padre. En general, esto conduce a más aislado, internamente consistente componentes (una buena cosa™). Pero, si la información que está pasando para que el niño realmente es un evento (o un comando), modificando el estado no es el patrón de la derecha. En ese caso, la llamada a un método que utiliza un ref es totalmente bien, y no va a crash ni nada.
    • Aquí, lo que en Brasil se llama «Gambiarra».
    • ¿Puede por favor explicar cómo esta respuesta hace que el acoplamiento y la R de Alegría respuesta no?

  2. 57

    Lo que está describiendo es un cambio de estado en el padre. Pasa que para el niño a través de una proposición. Como usted sugiere, sería watch que la prop. Cuando el niño se lleva a la acción, se notifica a los padres a través de un emit, y el padre puede, a continuación, cambiar el estado de nuevo.

    JS:

    var Child = {
      template: '<div>{{counter}}</div>',
      props: ['canI'],
      data: function () {
        return {
          counter: 0
        };
      },
      watch: {
        canI: function () {
          if (this.canI) {
            ++this.counter;
            this.$emit('increment');
          }
        }
      }
    }
    new Vue({
      el: '#app',
      components: {
        'my-component': Child
      },
      data: {
        childState: false
      },
      methods: {
        permitChild: function () {
          this.childState = true;
        },
        lockChild: function () {
          this.childState = false;
        }
      }
    })

    HTML:

    <script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.1/vue.js"></script>
    <div id="app">
    <my-component :can-I="childState" v-on:increment="lockChild"></my-component>
    <button @click="permitChild">Go</button>
    </div>

    Si usted realmente desea pasar eventos a un niño, usted puede hacer que por la creación de un autobús (que es sólo una Vue ejemplo) y pasar al niño como un prop.

    • Creo que esta es la única respuesta en línea con la oficial Vue.JS la guía de estilo y las mejores prácticas. Si utiliza la abreviatura v-model en el componente, también puede restablecer fácilmente el valor emitiendo el correspondiente evento con menos código.
    • Por ejemplo, quiero dar un aviso cuando un usuario hace clic en un botón. Qué proponen por ejemplo: – ver una bandera de establecer esta bandera de 0 a 1 cuando un clic se produce, – hacer algo de restablecimiento de la bandera
    • Yo no esperaría al niño a emitir una alerta por un clic en el padre, pero si eso es lo que quería hacer, me gustaría pasar un autobús para el niño y el padre o la madre emiten en el autobús.
    • Es muy incómodo, usted tiene que crear un extra de prop en un niño, una propiedad adicional en data, a continuación, añadir watch… sería cómodo si no fue incorporado en el soporte de alguna manera los fenómenos de transferencia de padres a hijos. Esta situación se produce muy a menudo.
    • Como estado por @ИльяЗеленько, sucede muy a menudo, sería un regalo del cielo ahora mismo.
  3. 26

    Puede utilizar $emit y $on. El uso de @RoyJ código:

    html:

    <div id="app">
      <my-component></my-component>
      <button @click="click">Click</button>  
    </div>

    javascript:

    var Child = {
      template: '<div>{{value}}</div>',
      data: function () {
        return {
          value: 0
        };
      },
      methods: {
        setValue: function(value) {
            this.value = value;
        }
      },
      created: function() {
        this.$parent.$on('update', this.setValue);
      }
    }
    
    new Vue({
      el: '#app',
      components: {
        'my-component': Child
      },
      methods: {
        click: function() {
            this.$emit('update', 7);
        }
      }
    })

    Ejemplo: https://jsfiddle.net/rjurado/m2spy60r/1/

    • Me sorprende que funciona. Pensé que emiten a un niño era un anti-patrón, o que la intención era que emiten sólo tener de hijo a padre. Hay problemas potenciales con la de la otra manera?
    • Esto no puede ser considerado como el mejor camino, no sé, pero Si sabes lo que estás haciendo, yo lo hay no es un problema. La otra forma es utilizar la central de autobuses: vuejs.org/v2/guide/…
    • Esto crea un acoplamiento entre el niño y el padre y se considera de mala práctica
    • Esto es sólo porque el padre no es un componente, pero en realidad un vue de la aplicación. En realidad, este es el uso de la vue ejemplo, como un autobús.
    • ¿Puede por favor explicar cómo esta respuesta hace que el acoplamiento y la R de Alegría respuesta no?
    • la llamada a esta.$los padres hace que este componente depende de los padres. utiliza $emiten y accesorios para la única de las dependencias a través de la Vue del sistema de comunicación. Este enfoque permite que el mismo componente para ser utilizado en cualquier lugar en la jerarquía de componentes.

  4. 6

    Si usted tiene el tiempo, el uso de Vuex de la tienda para la observación de variables (también conocido como estado) o gatillo (también conocido como despacho) una acción directamente.

    • debido a la reactividad de vuejs/vuex que es el mejor aproach, en los padres hacer una acción/mutación que cambiar un vuex valor de la propiedad y en el niño, tienen un valor calculado que conseguir este mismo vuex $store.estado.de la propiedad.valor o un «reloj», método que hacer algo cuando vuex «$de la tienda.estado.de la propiedad.el valor de» cambios
  5. 3

    No como el evento-bus de acercamiento utilizando $on enlaces en el niño durante create. Por qué? Posterior create llamadas (estoy usando vue-router) se unen al controlador de mensaje más de una vez-lo que conduce a múltiples respuestas por mensaje.

    La solución ortodoxa de pasar puntales de padre a hijo y de poner un vigilante de la propiedad en el niño trabajó un poco mejor. El único problema es que el niño sólo puede actuar en un valor de transición. Pasando el mismo mensaje varias veces las necesidades de algún tipo de contabilidad para forzar una transición para que el niño pueda recoger el cambio.

    He descubierto que si me envuelva el mensaje en una matriz, siempre va a desencadenar el niño observador, incluso si el valor sigue siendo el mismo.

    Padre:

    {
       data: function() {
          msgChild: null,
       },
       methods: {
          mMessageDoIt: function() {
             this.msgChild = ['doIt'];
          }
       }   
       ...
    }

    Niño:

    {
       props: ['msgChild'],
       watch: {
          'msgChild': function(arMsg) {
             console.log(arMsg[0]);
          }
       }
    }

    HTML:

    <parent>
       <child v-bind="{ 'msgChild': msgChild }"></child>
    </parent>
    • Creo que esto no funcionará si msgChild tiene siempre el mismo estado en el padre. Por ejemplo: quiero un componente que se abre un modal. El padre no se preocupa de si el estado actual es abrir o cerrar, sólo quiere abrir el modal en cualquier momento. Por lo tanto, si el padre no esta.msgChild = true; el modal es cerrado, y entonces el padre lo hace.msgChild = true, el niño no reciban el evento
    • Es por eso que estoy envolviendo el valor en una matriz antes de asignar el elemento de datos. Sin envolver el valor de una matriz, se comporta como usted especifique. Así, msgChild = true, msgChild = true — ningún caso. msgChild = [true], msgChild = [true] — evento!
    • Yo no lo veo. Gracias por la aclaración
    • Esto es genial, pero se siente un poco hackish. Voy a usar ya que es el más limpio que el uso de la componente ref hack y menos complicado que el bus de eventos de la solución. Sé que vue quiere disociación y sólo permitir los cambios de estado a efecto de que el componente pero debe haber algún builtin forma de llamar a un hijo métodos si es necesario. Tal vez un modificador en la proposición de que una vez que se cambia de estado podría restablecer automáticamente a un valor predeterminado, de modo que el observador está listo para el siguiente cambio de estado. De todos modos gracias por publicar su hallazgo.
  6. 3

    Un simple desacoplado manera de llamar a los métodos de niño componentes es mediante la emisión de un controlador de el niño y, a continuación, la invocación de los padres.

    JS:

    var Child = {
      template: '<div>{{value}}</div>',
      data: function () {
        return {
          value: 0
        };
      },
      methods: {
      	setValue(value) {
        	this.value = value;
        }
      },
      created() {
        this.$emit('handler', this.setValue);
      }
    }
    
    new Vue({
      el: '#app',
      components: {
        'my-component': Child
      },
      methods: {
      	setValueHandler(fn) {
        	this.setter = fn
        },
        click() {
        	this.setter(70)
        }
      }
    })

    HTML:

    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
    
    <div id="app">
      <my-component @handler="setValueHandler"></my-component>
      <button @click="click">Click</button>  
    </div>

    El padre mantiene un seguimiento del niño funciones de controlador y llamadas siempre que sea necesario.

    • Me gusta donde esta solución es la que va, pero ¿qué es exactamente «este.setter» en el padre?
    • Es la función establecervalor de referencia emitidos por el componente hijo como un argumento para controlador de evento.
  7. 2

    El ejemplo de abajo es la auto explainatory. donde los árbitros y los eventos se pueden utilizar para llamar a la función desde y para los padres y el niño.

    //PARENT
    <template>
      <parent>
        <child
          @onChange="childCallBack"
          ref="childRef"
          :data="moduleData"
        />
        <button @click="callChild">Call Method in child</button>
      </parent>
    </template>
    
    <script>
    export default {
      methods: {
        callChild() {
          this.$refs.childRef.childMethod('Hi from parent');
        },
        childCallBack(message) {
          console.log('message from child', message);
        }
      }
    };
    </script>
    
    //CHILD
    <template>
      <child>
        <button @click="callParent">Call Parent</button>
      </child>
    </template>
    
    <script>
    export default {
      methods: {
        callParent() {
          this.$emit('onChange', 'hi from child');
        },
        childMethod(message) {
          console.log('message from parent', message);
        }
      }
    }
    </script>
  8. 1

    Creo que debería tener una consideración acerca de la necesidad de los padres a utilizar el hijo métodos.De hecho,los padres no tienen la preocupación de que el método de niño,pero puede tratar al hijo como un componente de la FSA(máquina de estados finitos).Los padres de componentes para controlar el estado del componente secundario.Así que la solución para ver el cambio de estado o, simplemente, utilizar el cálculo de la función es suficiente

  9. 0

    Usted podría utilizar un mixin para establecer una compartido de datos de atributo. Cambio en el padre, mira en el niño:

    //mixin
    export default {
      data() {
        return  {
          clicked: false
        }
      }
    }
    
    //parent
    export default {
      mixins: [myMixin],
      methods: {
        btnClick() {
          this.clicked = true
        }
      }
    }
    
    //child
    export default {
      mixins: [myMixin],
      watch: {
        clicked(val) {
          if(val) {
            //yay
          }
        }
      }
    }
    • Por qué van a compartir los datos de atributo? Los componentes deben tener distintos contextos para el atributo, no?

Dejar respuesta

Please enter your comment!
Please enter your name here