web-dev-qa-db-fra.com

VueJS accéder aux données du composant enfant du parent

J'utilise le échafaud de vue-cli pour Webpack

Ma structure/hiérarchie de composant Vue ressemble actuellement à ceci:

  • App
    • Modèle PDF
      • Contexte
      • Modèle dynamique
      • Modèle statique
      • Réduction

Au niveau de l'application, je souhaite une méthode de composant vuejs capable d'agréger toutes les données du composant enfant en un seul objet JSON pouvant être envoyé au serveur. 

Existe-t-il un moyen d'accéder aux données du composant enfant? Plus précisément, plusieurs couches profondes?

Si ce n'est pas le cas, quelle est la meilleure pratique pour transmettre des données/paramètres oberservables, afin que, lorsqu'elles sont modifiées par des composants enfants, j'ai accès aux nouvelles valeurs? J'essaie d'éviter les dépendances entre les composants, donc pour l'instant, la seule chose transmise à l'aide d'attributs de composant sont les valeurs d'initialisation.

METTRE À JOUR:

Réponses solides. Ressources que j'ai trouvées utiles après avoir examiné les deux réponses:

33
Daniel Brown

Pour ce type de structure, il est bon d'avoir une sorte de magasin.

VueJS fournit une solution pour cela, et s'appelle Vuex. Si vous n'êtes pas prêt à utiliser Vuex, vous pouvez créer votre propre magasin simple.

Essayons avec ça

MarkdownStore.js

export default {

 data: {
   items: []
 },

 // Methods that you need, for e.g fetching data from server etc.

 fetchData() {
   // fetch logic
 }

}

Et maintenant, vous pouvez utiliser ces données partout, grâce à l'importation de ce fichier Store

HomeView.vue

import MarkdownStore from '../stores/MarkdownStore'

export default {

 data() {
   sharedItems: MarkdownStore.data
 },

 created() {
   MarkdownStore.fetchData()
 }

}

Voilà donc le flux de base que vous pouvez utiliser, si vous ne voulez pas utiliser Vuex.

31
Belmin Bedak

quelle est la meilleure pratique pour transmettre des données/paramètres oberservables, afin que, lorsqu'elles sont modifiées par des composants enfants, j'ai accès aux nouvelles valeurs?

Le flux d'accessoires est à sens unique, un enfant ne devrait jamais modifier ses accessoires directement.

Pour une application complexe, vuex est la solution, mais pour un cas simple, vuex est excessif. Comme ce que @Belmin a dit, vous pouvez même utiliser un objet JavaScript simple pour cela, grâce au système de réactivité.

Une autre solution consiste à utiliser des événements. Vue a déjà implémenté l'interface EventEmitter, un enfant peut utiliser this.$emit('eventName', data) pour communiquer avec son parent.

Le parent écoutera l'événement comme suit: (@update est le raccourci de v-on:update)

<child :value="value" @update="onChildUpdate" />

et mettez à jour les données dans le gestionnaire d'événements:

methods: {
  onChildUpdate (newValue) {
    this.value = newValue
  }
}

Voici un exemple simple d'événements personnalisés dans Vue:
http://codepen.io/CodinCat/pen/ZBELjm?editors=1010

Ceci est juste une communication parent-enfant, si un composant a besoin de parler à ses frères et sœurs, vous aurez besoin d'un bus d'événements global. Dans Vue.js, vous pouvez simplement utiliser une instance Vue vide:

const bus = new Vue()

// In component A
bus.$on('somethingUpdated', data => { ... })

// In component B
bus.$emit('somethingUpdated', newData)
16
CodinCat

Je ne suis pas sûr que ce soit une bonne pratique ou non.

Dans mon composant enfant, il n'y a pas de boutons pour émettre des données modifiées. sa forme avec un peu 5 ~ 10 entrées. les données seront soumises une fois que vous aurez cliqué sur le bouton de processus d'un autre composant. alors, je ne peux pas émettre toutes les propriétés quand elles changent.

Alors, ce que j'ai fait,

Dans ma composante parent, je peux accéder aux données de l'enfant à partir de "ref"

par exemple

<markdown ref="markdowndetails"></markdown>
<app-button @submit="process"></app-button>

// js
methods:{
    process: function(){
        // items is defined object inside data()
        var markdowns = this.$refs.markdowndetails.items 
    }
}

Note: Si vous faites cela partout dans l'application, je suggère de passer à vuex à la place.

0
PJ3