一、Vue官方文檔說明
在 Vue 中,父子元件的關系可以總結為 prop 向下傳遞,事件向上傳遞。父元件通過 prop給子元件下發資料,子元件通過事件給父元件發送消息。看看它們是怎麼工作的。

- - - - - - - - - - - - - - - - ✂- - - - - - - - - - - - - -✂-- - - - - - -- - - - - - - -✂- - - - - - -- - - - - - - - - -
二、父子元件消息傳遞示例
1.父元件傳遞資料給子元件
父元件資料如何傳遞給子元件呢?
使用 Prop 傳遞資料
元件執行個體的作用域是孤立的。這意味着不能 (也不應該) 在子元件的模闆内直接引用父元件的資料。父元件的資料需要通過 prop 才能下發到子元件中。
<parent>
<child :child-msg="msg"></child> //這裡必須要用 - 代替駝峰
</parent>
data(){
return {
msg: [1,2,3]
};
}
子元件要顯式地用
props
選項聲明它預期的資料:
Vue.component('child', {
// 聲明 props
props: ['childMsg'],
// 就像 data 一樣,prop 也可以在模闆中使用
// 同樣也可以在 vm 執行個體中通過 this.childMsg 來使用
template: '<span>{{ childMsg }}</span>'
})
PS:
props
選項說明:
方式1:
props: ['childMsg']
方式2 :
props: {
childMsg: Array // 這樣可以指定傳入的類型,如果類型不對,會警告
}
方式3:
props: {
childMsg: {
type: Array,
default: [0,0,0] // 這樣可以指定預設的值
}
}
這樣呢,就實作了父元件向子元件傳遞資料
2.子元件與父元件通信
那麼,如果子元件想要改變資料呢?這在vue中是不允許的,因為vue隻允許單向資料傳遞,這時候我們可以通過觸發事件來通知父元件改變資料,進而達到改變子元件資料的目的.
2.1 子元件:
<template>
<div @click="tellParent"></div>
</template>
methods: {
tellParent() {
this.$emit('toParent', 'Hi, father!'); // 主動觸發toParent方法,'Hi, father!'為向父元件傳遞的資料
}
}
2.2 父元件:
<parent>
<child @toParent="change" :msg="msg"></child> // 監聽子元件觸發的toParent事件, 然後調用change方法
</parent>
methods: {
change(msg) {
this.msg = msg;
}
}
3.非父子元件通信
如果2個元件不是父子元件那麼如何通信呢?這時可以通過eventHub來實作通信. 所謂eventHub就是建立一個事件中心,相當于中轉站,可以用它來傳遞事件和接收事件.
3.1 在共有元件中,建立一個空的 Vue 執行個體作為事件中心:
let Hub = new Vue(); //建立事件中心
元件1:
<template>
<a @click="event"></a>
</template>
methods: {
event () {
Hub.$emit('myEvent', 'Hi, there!'); // Hub觸發事件自定義事件‘myEvent’,并傳遞資訊“Hi, there!”
}
}
元件2:
<template>
<p>{{ message }}</p>
</template>
data() {
return {
message: '',
}
},
created() {
Hub.$on('myEvent', (msg) => { // Hub接收事件“myEvent”,并接受傳遞的資訊msg
this.message = msg;
});
}
這樣就實作了非父子元件之間的通信了.原理就是把Hub當作一個中轉站!
3.2 在main.js(vue-cli腳手架建立的項目)中,給data添加一個 名字為Hub的空vue對象
這時候,在任何元件都可以調用事件發射 接受的方法了。
// 根元件(this.$root)
new Vue({
el: '#app',
router,
render: h => h(App),
data: {
// 空的執行個體放到根元件下,所有的子元件都能調用
Hub: new Vue()
}
})
假設 B 元件裡面有個按鈕,點選按鈕,把 123 傳遞給 A 元件
3.2.1 B元件内調用事件觸發↓
<button @click="submit">送出<button>
methods: {
submit() {
// 通過this.$root.Hub擷取此對象,再調用$emit方法
this.$root.Hub.$emit('YOUR_EVENT_NAME', 123)
}
}
A元件内調用事件接收↓
// 目前執行個體建立完成就監聽這個事件
created(){
this.$root.Hub.$on('YOUR_EVENT_NAME', (yourData) => {
handle(yourData)
})
},
methods: {
handle(yourData) {
console.log(yourData)
}
},
// 在元件銷毀時别忘了解除事件綁定
beforeDestroy() {
this.$root.Hub.$off('YOUR_EVENT_NAME')
},