2016-07-27 8 views
27

In vuejs 2.0 model.sync wird deprecated sein.Kommunikation zwischen Geschwisterkomponenten in VueJs 2.0

Also, was ist eine richtige Art der Kommunikation zwischen Geschwisterkomponenten in vuejs 2.0?

Wie ich die Idee in Vue 2.0 fangen ist Geschwister Kommunikation haben durch einen Laden oder ein Event-Bus.

Nach evan:

Es ist auch erwähnenswert ist „Daten zwischen den Komponenten passing“ generell eine schlechte Idee, denn am Ende wird der Datenfluss nicht protokollierbare und sehr schwer zu debuggen.

Wenn ein Teil der Daten von mehreren Komponenten gemeinsam genutzt werden muss, bevorzugen Sie global stores oder Vuex.

[Link to discussion]

Und:

.once und .sync sind veraltet. Requisiten sind jetzt immer in einer Richtung. Um Nebenwirkungen im übergeordneten Bereich zu erzeugen, muss eine Komponente explizit emit ein Ereignis anstelle der impliziten Bindung.

(So, er suggest ist $emit und $on zu verwenden)

Ich mache mir Sorgen wegen:

  • Jeder store und event eine globale Sichtbarkeit (korrigieren Sie mich, wenn ich mich falsch);
  • Es ist zu viel, um einen neuen Laden für jede kleine Kommunikation zu schaffen;

Was ich will, ist Umfang irgendwie events oder stores Sichtbarkeit für Geschwister Komponenten. Oder ich habe die Idee nicht verstanden.

Also, wie kommunizieren auf richtige Weise?

+1

'emit' $ kombiniert mit' V-Modell 'zu emulieren '.sync'. Ich denke, du solltest den Vuex Weg gehen – eltonkamami

+2

Also habe ich die gleiche Sorge berücksichtigt. Meine Lösung besteht darin, einen Event-Emitter mit einem Broadcast-Kanal zu verwenden, der äquivalent zu "scope" ist - dh ein Kind/Eltern und Geschwister-Setup verwenden den gleichen Kanal für die Kommunikation. In meinem Fall verwende ich die Radiobibliothek http://radio.uxder.com/, weil es nur ein paar Zeilen Code ist und kugelsicher, aber viele würden den Knoten EventEmitter wählen. –

Antwort

34

Mit Vue 2.0, ich bin der eventHub Mechanismus wie in den documentation demonstriert.

  1. Definieren Sie einen zentralen Event-Hub.

    const eventHub = new Vue() // Single event hub 
    
    // Distribute to components using global mixin 
    Vue.mixin({ 
        data: function() { 
         return { 
          eventHub: eventHub 
         } 
        } 
    }) 
    
  2. Jetzt in Ihrer Komponente können Sie emittieren Ereignisse mit

    this.eventHub.$emit('update', data) 
    
  3. Und Sie

    this.eventHub.$on('update', data => { 
    // do your thing 
    }) 
    
    tun zu hören
+2

Nur ein Blick nach oben: Behalten Sie Global Mixins im Auge und versuchen Sie diese nach Möglichkeit zu meiden, da sie gemäß diesem Link https://vuejs.org/v2/guide/mixins.html#Global-Mixin sogar Dritte beeinflussen können Party-Komponenten. –

5

Was ich normalerweise mache, wenn ich die normalen Kommunikationsmuster in Vue "hacken" möchte, speziell jetzt, wo .sync veraltet ist, ist es, einen einfachen EventEmitter zu erstellen, der die Kommunikation zwischen Komponenten abwickelt.Von einem meiner aktuellen Projekte:

import {EventEmitter} from 'events' 

var Transmitter = Object.assign({}, EventEmitter.prototype, { /* ... */ }) 

Mit diesem Transmitter Objekt können Sie dann tun, in jeder Komponente:

import Transmitter from './Transmitter' 

var ComponentOne = Vue.extend({ 
    methods: { 
    transmit: Transmitter.emit('update') 
    } 
}) 

Und eine "empfangenden" Komponente zu erstellen:

import Transmitter from './Transmitter' 

var ComponentTwo = Vue.extend({ 
    ready: function() { 
    Transmitter.on('update', this.doThingOnUpdate) 
    } 
}) 

Auch dies ist für wirklich spezifische Anwendungen. Basieren Sie Ihre gesamte Anwendung nicht auf diesem Muster, verwenden Sie stattdessen etwas wie Vuex.

+1

Ich benutze bereits 'vuex', aber sollte ich auch den vuex's store für jede kleinere Kommunikation erstellen? –

+0

Es ist schwer für mich, mit dieser Menge an Informationen zu sagen, aber ich würde sagen, wenn du schon 'vuex' verwendest, dann mach es. Benutze es. –

+1

Eigentlich würde ich nicht zustimmen, dass wir Vuex für jede kleine Kommunikation verwenden müssen ... – Victor

3

Okay, wir können zwischen Geschwistern über Eltern über v-on Ereignisse kommunizieren.

Parent 
|-List of items //sibling 1 - "List" 
|-Details of selected item //sibling 2 - "Details" 

Nehmen wir an, dass wir Details Komponente aktualisieren möchten, wenn wir ein Element in List klicken.


in Parent:

Vorlage:

<list v-model="listModel" 
     v-on:select-item="setSelectedItem" 
></list> 
<details v-model="selectedModel"></details> 

hier:

  • v-on:select-item Es ist ein Ereignis, das in List Komponente (siehe unten) genannt wird;
  • setSelectedItem es ist eine Parent Methode zu aktualisieren selectedModel;

JS:

//... 
data() { 
    return { 
    listModel: ['a', 'b'] 
    selectedModel: null 
    } 
}, 
methods: { 
    setSelectedItem (item) { 
    this.selectedModel = item //here we change the Detail's model 
    }, 
} 
//... 

In List:

Vorlage:

<ul> 
    <li v-for="i in list" 
     :value="i" 
     @click="select(i, $event)"> 
     <span v-text="i"></span> 
    </li> 
</ul> 

JS:

//... 
data() { 
    return { 
    selected: null 
    } 
}, 
props: { 
    list: { 
    type: Array, 
    required: true 
    } 
}, 
methods: { 
    select (item) { 
    this.selected = item 
    this.$emit('select-item', item) // here we call the event we waiting for in "Parent" 
    }, 
} 
//... 
Hier

:

  • this.$emit('select-item', item) werden Artikel über select-item direkt in Mutter senden. Und Eltern werden es die Details Ansicht senden
11

können Sie es sogar kürzer machen und verwenden rootVue Instanz als globaler Event-Hub:

Komponente:

this.$root.$emit('eventing', data); 

Komponente 2:

mounted() { 
    this.$root.$on('eventing', data => { 
     console.log(data); 
    }); 
} 
+2

Dies funktioniert perfekt, ausgezeichnete und sehr übersichtliche Lösung. – Mateo

+0

Dies funktioniert besser als das Definieren eines Additions-Ereignis-Hubs und das Anhängen an einen Event-Consumer. – schad