web-dev-qa-db-fra.com

Vue.js - accéder aux données de l'instance racine dans le composant

Cela semble être une question assez basique mais je n'arrive pas à trouver une réponse définitive (ou même fonctionnelle).

J'ai mon instance racine:

var vm = new Vue({
  el: '#app',

  // Data
  data: {
      events: {}
  },

  // Methods
  methods: {

    fetchEvents: function(){
      this.$http.get('/api/events').success(function(theseEvents) {
      this.$set('events', theseEvents);

      }).error(function(error) {

      });

    }
},

ready: function(){

  this.fetchEvents();

}

});

Et j'ai un composant séparé dans lequel je veux lister les événements qui sont stockés dans l'instance racine. Pour le moment, cela ressemble à ceci:

var EventsList = Vue.extend({

template: '<ul><li v-for="event in events"><h2>{{ event.title }}</h2><p>{{ event.body }}</p></li></ul>',

data: function(){
  return {
    events: {}
  }
},

methods: {

  syncEvents: function(){
    this.$set('events', this.$parent.events);
  }

},

// When ready...
ready: function(){
  this.syncEvents();
}
}

Cela ne semble pas fonctionner. J'ai aussi essayé this.$root.events en vain. Quelle est la bonne façon de procéder? Gardez à l'esprit que je veux référencer les données à partir de la racine, pas créer une copie avec sa propre portée.

EDIT: en essayant d'utiliser des accessoires, voici le composant liste, qui ne fonctionne pas non plus:

var EventsList = Vue.extend({

template: '<ul><li v-for="event in events"><h2>{{ event.title }}</h2><p>{{ event.body }}</p></li></ul>',

props: ['events']

}
12
Chris

En utilisant props , vous pouvez facilement transmettre les mêmes données du parent aux enfants. Puisque je ne sais pas comment vous avez lié l'instance racine et le EventList ensemble, je vais supposer que vous l'avez enregistré en tant que composant global.

La documentation indique:

Notez que si l'hélice transmise est un objet ou un tableau, elle est transmise par référence. La mutation de l'objet ou du tableau lui-même à l'intérieur de l'enfant affectera l'état parent, quel que soit le type de liaison que vous utilisez.

Vous utiliserez donc le même objet dans tous vos composants lorsque vous le passerez comme accessoire.

var vm = new Vue({
  el: '#app',

  // Data
  data: {
      events: {}
  },

  // Methods
  methods: {

    fetchEvents: function(){
      this.$http.get('/api/events').success(function(theseEvents) {
      this.$data.events = theseEvents; // You don't need to use $set here

      }).error(function(error) {

      });

    }
},

ready: function(){

  this.fetchEvents();

}

});

Liste des événements:

var EventsList = Vue.extend({

template: '<ul><li v-for="event in events"><h2>{{ event.title }}</h2><p>{{ event.body }}</p></li></ul>',

data: function(){
  return {
  }
},
props: {
    events: Object, // assuming that your prop is an object
},
}

// Register the vue component globally, if you want to:
Vue.component('eventlist', EventsList);

Dans le modèle d'instance racine vue, vous pouvez passer la racine vue instances events en tant que propriété appelée events dans le composant enfant:

<div class="app">
    <!-- events is passed using the :events prop -->
    <eventlist :events="events">
    </eventlist>
</div>
5
nils

C'est à ça que servent les "accessoires":

http://vuejs.org/guide/components.html#Props

Si vous passez un objet/tableau comme accessoire (quelles seront vos données events sûrement), c'est une synchronisation bidirectionnelle automatiquement - changez les événements dans l'enfant, ils sont changés dans le parent.

Si vous passez des valeurs simples (chaînes, nombres - par exemple uniquement event.name) via des accessoires, vous devez utiliser explicitement le .sync modificateur: http://vuejs.org/guide/components.html#Prop_Binding_Types

1
Linus Borg