Pasar datos a componentes en vue.js


Estoy luchando para entender cómo pasar datos entre componentes en vue.js. He leído los documentos varias veces y he mirado muchas preguntas y tutoriales relacionados con vue, pero todavía no lo estoy entendiendo.

Para envolver mi cabeza alrededor de esto, estoy esperando ayuda para completar un ejemplo bastante simple

  1. mostrar una lista de usuarios en un componente (hecho)
  2. enviar los datos de usuario a un nuevo componente cuando se hace clic en un enlace (hecho) - ver actualizar en inferior.
  3. edite los datos del usuario y envíelos de vuelta al componente original (no he llegado hasta aquí)

Aquí hay un violín, que falla en el paso dos: https://jsfiddle.net/retrogradeMT/d1a8hps0 /

Entiendo que necesito usar props para pasar datos al nuevo componente, pero no estoy seguro de cómo hacerlo funcionalmente. ¿Cómo enlazo los datos al nuevo componente?

HTML:

    <div id="page-content">
       <router-view></router-view>
     </div>

 <template id="userBlock" >
   <ul>
     <li v-for="user in users">{{user.name}} - <a v-link="{ path: '/new' }"> Show new component</a>
     </li>
   </ul>
 </template>

  <template id="newtemp" :name ="{{user.name}}">
    <form>
      <label>Name: </label><input v-model="name">
      <input type="submit" value="Submit">
    </form>
  </template>

Js para el componente principal:

Vue.component('app-page', {
  template: '#userBlock',

  data: function() {
    return{

        users: []
      }
    },

ready: function () {
    this.fetchUsers();
},

methods: {
    fetchUsers: function(){
        var users = [
          {
            id: 1,
            name: 'tom'
          },
          {
            id: 2,
            name: 'brian'
          },
          {
            id: 3,
            name: 'sam'
          },
        ];

        this.$set('users', users);
     }
    }
  })

JS para el segundo componente:

Vue.component('newtemp', {
  template: '#newtemp',
  props: 'name',
  data: function() {
    return {
        name: name,
        }
   },
})

ACTUALIZACIÓN

Ok, tengo el segundo paso resuelto. Aquí hay un nuevo violín que muestra el progreso: https://jsfiddle.net/retrogradeMT/9pffnmjp /

Debido a que estoy usando Vue-router, no uso props para enviar los datos a un nuevo componente. En su lugar, necesito establecer parámetros en el v-link y luego usar un gancho de transición para aceptarlo.

V-link changes ver rutas con nombre en vue-router docs :

<a v-link="{ name: 'new', params: { name: user.name }}"> Show new component</a>

Luego en el componente, agregue datos de las opciones de ruta ver ganchos de transición :

Vue.component('newtemp', {
  template: '#newtemp',
  route: {
   data: function(transition) {
        transition.next({
            // saving the id which is passed in url
            name: transition.to.params.name
        });
     }
  },
 data: function() {
    return {
        name:name,
        }
   },
})
 57
Author: retrograde, 2015-12-30

5 answers

-------------Siguiente es aplicable solamente a Vue 1 --------------

El paso de datos se puede hacer de varias maneras. El método depende del tipo de uso.


Si desea pasar datos de su html mientras agrega un nuevo componente. Eso se hace usando accesorios.

<my-component prop-name="value"></my-component>

Este valor de prop estará disponible para su componente solo si agrega el nombre de prop prop-name a su atributo props.


Cuando se pasan datos de un componente a otro componente debido a algún evento dinámico o estático. Esto se hace mediante el uso de despachadores de eventos y emisoras. Así, por ejemplo, si tienes una estructura de componentes como esta:

<my-parent>
    <my-child-A></my-child-A>
    <my-child-B></my-child-B>
</my-parent>

Y desea enviar datos de <my-child-A> a <my-child-B> entonces en <my-child-A> tendrá que enviar un evento:

this.$dispatch('event_name', data);

Este evento viajará hasta la cadena padre. Y desde cualquier padre que tenga una rama hacia <my-child-B> usted transmite el evento junto con los datos. Así que en el padre:

events:{
    'event_name' : function(data){
        this.$broadcast('event_name', data);
    },

Ahora esta transmisión viajará por la cadena infantil. Y en cualquier niño que desee agarrar el evento, en nuestro caso <my-child-B> agregaremos otro evento:

events: {
    'event_name' : function(data){
        // Your code. 
    },
},

La tercera forma de pasar datos es a través de parámetros en v-links. Este método se utiliza cuando las cadenas de componentes se destruyen completamente o en los casos en que el URI cambia. Y puedo ver que ya los entiendes.


Decida qué tipo de comunicación de datos desea y elija adecuadamente.

 30
Author: notANerdDev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-08 11:55:59

Creo que el tema está aquí:

<template id="newtemp" :name ="{{user.name}}">

Cuando antepones la propiedad con : estás indicando a Vue que es una variable, no una cadena. Así que no necesitas el {{}} alrededor de user.name. Try:

<template id="newtemp" :name ="user.name">

EDITAR-----

Lo anterior es cierto, pero el problema más grande aquí es que cuando cambias la URL y vas a una nueva ruta, el componente original desaparece. Para que el segundo componente edite los datos primarios, el segundo componente tendría que ser un componente secundario de la primero, o simplemente una parte del mismo componente.

 10
Author: Jeff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-12-30 17:54:25

La mejor manera de enviar datos de un componente padre a un hijo es usando props.

Pasar datos de padre a hijo a través de props

  • Declare props (array or object) en el hijo
  • Pasárselo al niño a través de <child :name="variableOnParent">

Ver demostración a continuación:

Vue.component('child-comp', {
  props: ['message'], // declare the props
  template: '<p>At child-comp, using props in the template: {{ message }}</p>',
  mounted: function () {
    console.log('The props are also available in JS:', this.message);
  }
})

new Vue({
  el: '#app',
  data: {
    variableAtParent: 'DATA FROM PARENT!'
  }
})
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>

<div id="app">
  <p>At Parent: {{ variableAtParent }}</p>
  <child-comp :message="variableAtParent"></child-comp>
</div>
 6
Author: acdcjunior,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-05 00:07:54

He encontrado una manera de pasar los datos del padre al ámbito del componente en Vue, creo que es un poco un poco de un truco, pero tal vez esto le ayudará.

1) Datos de referencia en la instancia de Vue como un objeto externo (data : dataObj)

2) Luego, en la función de retorno de datos en el componente hijo, simplemente devuelva parentScope = dataObj y listo. Ahora puedes hacer cosas como {{ parentScope.prop }} y funcionará como un encanto.

¡Buena Suerte!

 2
Author: Lucas Serena,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-07 08:46:58

Se puede usar una variable JS global (objeto) para pasar datos entre componentes. Ejemplo: Pasar datos desde Amlogin.vue a las opciones.vue. En Ammlogin.vue rspData se establece en la respuesta del servidor. En Opciones.vue la respuesta del servidor está disponible a través de rspData.

Índice.html:

<script>
    var rspData; // global - transfer data between components
</script>

Amlogin.vue:

....    
export default {
data: function() {return vueData}, 
methods: {
    login: function(event){
        event.preventDefault(); // otherwise the page is submitted...
        vueData.errortxt = "";
        axios.post('http://vueamm...../actions.php', { action: this.$data.action, user: this.$data.user, password: this.$data.password})
            .then(function (response) {
                vueData.user = '';
                vueData.password = '';
                // activate v-link via JS click...
                // JSON.parse is not needed because it is already an object
                if (response.data.result === "ok") {
                    rspData = response.data; // set global rspData
                    document.getElementById("loginid").click();
                } else {
                    vueData.errortxt = "Felaktig avändare eller lösenord!"
                }
            })
            .catch(function (error) {
                // Wu oh! Something went wrong
                vueData.errortxt = error.message;
            });
    },
....

Opciones.vue:

<template>
<main-layout>
  <p>Alternativ</p>
  <p>Resultat: {{rspData.result}}</p>
  <p>Meddelande: {{rspData.data}}</p>
  <v-link href='/'>Logga ut</v-link>
</main-layout>
</template>
<script>
 import MainLayout from '../layouts/Main.vue'
 import VLink from '../components/VLink.vue'
 var optData = { rspData: rspData}; // rspData is global
 export default {
   data: function() {return optData},
   components: {
     MainLayout,
     VLink
   }
 }
</script>
 1
Author: Kjelle J,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-16 16:34:28