2016-07-27 61 views
27

在vuejs 2.0 model.sync将是deprecatedVueJs 2.0中的同级组件之间的通信

那么,在vuejs 2.0的兄弟组件之间沟通的正确方法是什么?

正如我赶想法在Vue的2.0是通过使用一个商店或事件总线具有同级通信

根据evan

这也是值得一提的“组件之间传递数据”是 一般一个坏主意,因为最终的数据流变得 无法追踪并很难调试。

如果某个数据片段需要由多个组件共享,请使用 global storesVuex

[Link to discussion]

和:

.once.sync被弃用。道具现在一直是单向的。在 在父范围内产生副作用时,组件需要明确emit事件而不是依赖于隐式绑定。

(所以,他suggest是使用$emit$on

我很担心,因为:

  • 每个storeevent具有全球知名度(纠正我,如果我错误);
  • 这对于为每个次要交流创建一个新商店非常重要;

我要的是范围莫名其妙eventsstores知名度兄弟姐妹组成部分。或者我也许没有理解这个想法。

那么,如何以正确的方式沟通?

+1

'$ emit'用'V-model'组合来模拟'.sync'。我认为你应该去Vuex的方式 – eltonkamami

+2

所以我也考虑过同样的担忧。我的解决方案是使用带有广播频道的事件发射器,该广播频道等同于'范围' - 即子/父母和兄弟设置使用相同的频道进行通信。在我的情况下,我使用无线电库http://radio.uxder.com/,因为它只是几行代码和它的防弹,但很多会选择节点EventEmitter。 –

回答

34

随着Vue的2.0,我使用的eventHub机制在documentation证明。

  1. 定义集中式事件中心。

    const eventHub = new Vue() // Single event hub 
    
    // Distribute to components using global mixin 
    Vue.mixin({ 
        data: function() { 
         return { 
          eventHub: eventHub 
         } 
        } 
    }) 
    
  2. this.eventHub.$emit('update', data) 
    
  3. 而现在,在你的组件,你可以发出事件来听你做

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

只是站起来:留意Global Mixins,并尽量避免使用它们,因为根据此链接https://vuejs.org/v2/guide/mixins.html#Global-Mixin,它们可能会影响到第三方派对组成部分。 –

5

如果我想要“破解”Vue中的正常通信模式(特别是现在不支持.sync),通常会做的是创建一个处理组件之间通信的简单EventEmitter。从我的最新项目之一:

import {EventEmitter} from 'events' 

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

有了这个Transmitter对象,那么你可以做,在任何组件:

import Transmitter from './Transmitter' 

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

并创建一个 “接收” 组件:

import Transmitter from './Transmitter' 

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

再次,这是为了真正的特定用途。不要将你的整个应用程序放在这个模式上,而应该使用类似Vuex的东西。

+1

我已经使用'vuex',但是我应该再次为每个次要通信创建vuex的商店吗? –

+0

我很难用这些信息来说,但我会说,如果你已经在使用'vuex'是的,那就去吧。用它。 –

+1

其实我不同意我们需要使用vuex来处理每个小问题...... – Victor

3

好的,我们可以通过父母使用v-on事件进行兄弟姐妹之间的沟通。

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

假设我们要更新Details组件时,我们在List单击某个元素。


Parent

模板:

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

这里:

  • v-on:select-item这是一个事件,将在List组件调用(见下文);
  • setSelectedItem这是一个Parent的方法来更新selectedModel;

JS:

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

List

模板:

<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" 
    }, 
} 
//... 

这里:

  • this.$emit('select-item', item)将直接在父母通过select-item送项目。和家长将其发送到Details视图
11

你甚至可以把它缩短,并使用rootVue实例作为全局事件中心:

组分1:

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

组分2:

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

这是完美的,出色的和非常简洁的解决方案。 – Mateo

+0

这比定义一个附加事件集线器并将其附加到任何事件消费者更好。 – schad