2016-07-27 67 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