Comunicación de componente hijo a componente padre

En un tutorial anterior ya vimos cómo enviar información de un componente padre a un componente hijo usando los muy conocidos props. La comunicación en dirección contraria, de componente hijo a componente padre, es un poco más engorrosa, pero esto tiene una razón de ser.

En este tutorial veremos cómo es que se da esta comunicación y cómo podemos enviar información del componente hijo al componente padre en Vuejs.

Índice

  1. Emitiendo en el componente hijo
  2. Recepcionando en el componente padre
  3. Declarando eventos con parámetros
  4. Tu turno

1. Emitiendo en el componente hijo

Hay un principio que se debe respetar al trabajar con componentes. Este es que un componente hijo nunca debería modificar directamente las propiedades de un componente padre. Este es un principio muy importante, ya que si no se cumple nos podría traer algunos problemas. Sin embargo, esto no puede evitar que exista la necesidad de enviar información, por ejemplo, tomemos el caso de un componente input dentro de un componente formulario. El input debería ser capaz de enviar información al componente formulario.

Lo que debe realizar en este caso es hacer que el componente hijo notifique al componente padre del envío de información junto con el valor de la información. Esta notificación se emite en el componente hijo, para que luego pueda ser escuchado por el componente padre. Es así que debemos lanzar un emit del componente hijo al componente padres para notificar un valor, veamos el siguiente ejemplo.

<template>
  <div>
    <textarea v-model="message"></textarea>
  </div>
</template>
<script>
  export default {
    name: 'MyInput',
    components: {},
    data() {
      return {
        message: 'Hello world',
      }
    },
    watch: {
      message: function () {
        this.$emit('message', this.message)
      }
    }
</script>

En el ejemplo anterior, usamos un watch para emitir el valor del mensaje cada vez que su valor cambie. Como puedes ver el $emit utiliza dos parámetros. El primero es el nombre del emit y el segundo es el valor que se está emitiendo.

2. Recepcionando en el componente padre

La forma de recepcionar el valor que fue emitido en el componente hijo es definiendo un evento @nombre-evento en el componente hijo declarado en el componente padre. Veamos el siguiente ejemplo.

<!--Componente padre-->
<template>
  <div>
    <!--Componente hijo-->
    <my-input @message="handleMessage"></my-input>
    <h4>{{myMessage}}</h4>
  </div>
</template>
<script>
  import MyInput from "../components/MyInput.vue";

  export default {
    name: "Aboud",
    data() {
      return {
        myMessage: "",
      };
    },
    components: {
      MyInput,
    },
    methods: {
      handleMessage(value) {
        this.myMessage = value;
      },
    },
  };
</script>

Este evento ejecuta el método handleMessage definido en nuestro componente padre. Este método recibe un parámetro llamado value que contiene el valor que es emitido en el componente hijo. Este valor es almacenado en una variable local llamada myMessage y luego mostrada en el <template>.

El componente hijo también puede emitir un evento sin ningun valor. Por lo que al emitirse dicho evento solo notificará al componente padre ejecutando un método asociado a este, que puede no contener ningun parámetro.

3. Declarando eventos con parámetros

Si por algún motivo buscas que el método que creaste para el evento @nombre-evento tenga un parámetro en el template, lo único que debes hacer es agregar el parámetro que necesitamos seguido del parámetro $event que será el que represente a value. Veamos el siguiente ejemplo.

<template>
  <div>
    <my-input @message="handleMessage('AndyGeek', $event)"></my-input>
    <h4>{{myMessage}}</h4>
  </div>
</template>
<script>
  import MyInput from "../components/MyInput.vue";

  export default {
    name: "Aboud",
    data() {
      return {
        myMessage: "",
      };
    },
    components: {
      MyInput,
    },
    methods: {
      handleMessage(sufijo, $event) {
        this.myMessage = $event + sufijo;
      },
    },
  };
</script>

Como puedes ver ahora utilizamos el parámetro $event para representar al valor enviado desde el componente hijo.

4. Tu turno

Acabamos de ver cómo es que se envían datos de un componente hijo a su componente padre. Ahora es tu turno de crear tus propios componentes anidados y establecer una comunicación bidireccional entre ellos. Inténtalo!!