en Sin categoría

Cambiar valores de app a los componentes y viceversa

bidirectional reactive vue app to component
En este apunte intento poder comunicar desde la app al componente y viceversa.

Creamos el componente my-component.vue

<template>
    <div class="div_component">
        <input 
        v-model="message" 
        @keyup="changeMessage">
        <p>Message en componente es: {{message}}</p>
    <div>
</template>

<script>
module.exports = {
    data: function () {
        return {
          message: this.level
        }
      },
    ready:function(){},
    methods: {
        changeMessage: function(){
            console.log(this.message);
            this.$emit('change-message',this.message);
        }
    },
    props: 
    {
        level: {
            required: true
        }
    }
}
</script>

<style>
.div_component {
    background-color: rgb(204, 24, 114);
    padding: 10px;
    margin: 10px;
}
</style>

Donde level, es la propiedad que asignará el padre al componente, y con ese valor iniciamos el valor de message, que será la variable reactiva, después en <template> relacionamos v-model y escuchamos cuando cambie con @keyup.

La parte importante para transmitir los cambios al padre es la función $emit, donde el primer parámetro ‘change-message’ debe coincidir con el nombre que indiquemos al insertar el componente.

Definimos index.html

<!doctype html>
<html lang="en">
  <head>
    <script src="https://unpkg.com/vue"></script>
    <script src="https://unpkg.com/http-vue-loader"></script>
    <style>
        .div_padre{
            background: blueviolet;
            padding: 10px;
        }
    </style>
  </head>

  <body>
    <div id="my-app">
      <div class="div_padre">
        <!--
        -->
        <input
        @keyup="updateMessageChild"  
        v-model="message"></input> 
        <my-component 
        ref="componentChild" 
        :level="message" 
        @change-message="message = $event"></my-component>
      </div>
        
    </div>

    <script src="app.js" ></script>
  </body>
</html>

En index.html agregamos el componente my-component, indicamos ref, para tener una referencia desde app y poder actualizarlo, :level, es para indicar el dato inicial y @change-message, es para escuchar cuando el componente llame a $emit.

Ahora definimos app.js

new Vue({
    el: '#my-app',
    components: {
         'my-component': httpVueLoader('./my-component.vue')
    },
    data () {
        return {
             message:"ejemplo"
            }
        },
    methods: {
        
        updateMessageChild:function(){
            this.$refs.componentChild.message = this.message;
        }
        
    }
});

En app.js, el método updateMessageChild sirve para escuchar los cambios de message y poder actualizar el componente con this.$ref.componentChild donde componentChild es el nombre de la referencia al componente que indicamos por medio de ref.

Se debería comportar así

Código:
*Lo modifique un poco porque codesandbox mostraba errores al código original.

link: https://27rog.csb.app/

Notas:

Revisando básicamente, vue recomienda que cualquier paso de valor entre componentes sea definido y no directo, es posible pero altamente no recomendable.

No he profundizado mucho con este ejemplo, pero para otros casos mas complejos, considerar las limitantes descritas en la documentación https://es.vuejs.org/v2/guide/reactivity.html

Otro articulo interesante que estoy revisando:
https://alligator.io/vuejs/component-communication/

Escriba un comentario

Comentario