Enviar datos de un componente hijo al padre en Vue.js
En un post anterior vimos Cómo Crear un componente en Vue.js y cómo enviar parámetros a un componente en Vue desde la instancia principal. El día de hoy veremos como hacer lo opuesto, enviar parámetros o información desde un componente hijo al padre.
Para pasar información a un componente padre primero debemos saber cómo es la comunicación entre componentes en Vue. En el post mencionado anteriormente vimos que es posible enviar parámetros a los componentes gracias al objeto props. Sin embargo, un componente se comunica con su padre a través de eventos. A su vez, estos eventos son emitidos a través del método $emit
.
Método $emit en Vue.js
Con el método $emit podemos lanzar un evento creado por nosotros mismos para ser capturado en la declaración del componente. Para entender esto, supongamos que tenemos un formulario en nuestro código HTML y un botón de submit en un componente por fuera de dicho formulario. Lo que queremos hacer es que dicho botón envie un evento que cambie el estado del formulario y le agregue una clase llamada loading.
<div id="app" class="m-3">
<form :class="formClass">
<div class="form-group">
<label for="email">Email address</label>
<input type="email" class="form-control" id="email">
</div>
</form>
<x-button
text="Submit"
v-on:submit-form="formClass = 'loading'"></x-button>
</div>
Como puedes ver estamos utilizando el enlace de atributos para hacer un bind de la clase del formulario con una propiedad llamada formClass
. Por otro lado, fuera del formulario tenemos un componente llamada x-button que deberá escuchar un evento llamado submit-form
que cambiará el valor de la propiedad formClass a loading.
Ahora bien, veamos ahora la definción del componente.
Vue.component('x-button', {
props: ['text'],
template: `
<button type="submit" class="btn btn-primary" v-on:click="$emit('submit-form')">
{{ '\{\{ text \}\}' }}
</button>
`
});
var vue = new Vue({
el: "#app",
data: {
formClass: ''
}
})
Observa que en la definción del template de nuestro componente hemos utilizado el método $emit('submit-form')
para lanzar dicho eventos cuando se haga clic en el botón. Este evento será escuchado por x-button y cambiará la clase del formulario como vimos anteriormente. Veamos este ejemplo en ejecución en codepen.
Finalmente, para pasar datos desde el componente hijo hacia el padre basta enviar más parámetros al método $emit
. En este caso, podemos pasar directamente el nombre de la clase que queremos asignar al formulario.
v-on:click="$emit('submit-form', 'loading')"
Por otro lado, para poder recibir este parámetro debemos crear un método en la instancia de Vue así:
methods: {
changeFormState: function(className) {
this.formClass = className;
}
}
Para que esto funcione también debemos cambiar la expresión en el evento.
<x-button
text="Submit"
v-on:submit-form="changeFormState"></x-button>
El resultado será exactamente el mismo visto anteriormente con la diferencia que hemos pasado el dato del nombre de la clase desde el componente hijo hacia el padre.