在 Vue 中,父子組件之間的關(guān)系可以概述為:props 向下,events 向上仅胞。父組件通過 props 向下傳遞數(shù)據(jù)給子組件每辟,子組件通過 events 發(fā)送消息給父組件。
(1)父傳子
1.父組件調(diào)用子組件時傳入變量log-content:
<log ref="log" :log-content="logContent"></log>
2.子組件通過props接收父組件傳來的變量(可傳遞多個變量)
<template>
<div class="log-content">
<pre v-text="logContent|| '暫無內(nèi)容'"></pre>
</div>
</template>
export default {
// ...
props: ['logContent']// 像 data 一樣干旧,prop 可以在組件模板內(nèi)部使用渠欺,并且,還可以在 vm 實例中通過 this.logContent訪問
}
總結(jié):
1.不能(也不應(yīng)該)直接在子組件模板中引用父組件數(shù)據(jù)椎眯,應(yīng)該使用props 將數(shù)據(jù)向下傳遞到子組件挠将。
2.當(dāng)父組件屬性更新,數(shù)據(jù)就會向下流動到子組件
(2)子傳父
1.父組件使用 v-on 監(jiān)聽子組件觸發(fā)的事件close(自定義事件)
<log ref="log" :log="logContent" v-on:close="closeLog"></log>
export default {
// ...
methods: {
closeLog (data) {
console.log(data) // 子組件通過emit傳遞數(shù)據(jù)給父組件
}
}
}
2.子組件可通過$emit觸發(fā)close事件编整,從而將自身內(nèi)部的信息全部通知到父組件中捐名。
<template>
<div class="log-content">
<pre v-text="logContent|| '暫無內(nèi)容'"></pre>
<button v-on:click="handleClose">關(guān)閉</button>
</div>
</template>
export default {
data () {
return {
text: '當(dāng)關(guān)閉log時,子組件傳遞數(shù)據(jù)給父組件'
}
},
props: ['logContent'],
// ...
methods: {
handleClose () {
this.$emit('close', this.text)
}
}
}
總結(jié):
1.父組件監(jiān)聽子組件的事件(使用 emit(eventName) 觸發(fā)闹击,可以傳遞參數(shù)
3.父組件接收到監(jiān)聽,執(zhí)行自身事件成艘,實現(xiàn)數(shù)據(jù)更改
(3)摘自官網(wǎng)
所有的 props 都是在子組件屬性和父組件屬性之間綁定的赏半,按照自上而下單向流動方式構(gòu)成:當(dāng)父組件屬性更新,數(shù)據(jù)就會向下流動到子組件淆两,但是反過來卻并非如此断箫。這種機制可以防止子組件意外地修改了父組件的狀態(tài),會造成應(yīng)用程序的數(shù)據(jù)流動變得難于理解秋冰。
此外仲义,每次父組件更新時,子組件中所有的 props 都會更新為最新值剑勾。也就是說埃撵,你不應(yīng)該試圖在子組件內(nèi)部修改 prop。如果你這么做虽另,Vue 就會在控制臺給出警告暂刘。
注意,在 JavaScript 中對象和數(shù)組會作為引用類型傳入捂刺,因此谣拣,如果 prop 是一個對象或數(shù)組,在子組件內(nèi)部修改對象或數(shù)組自身族展,將會影響父組件的狀態(tài)森缠。
二、非父子組件通信
使用一個空的 Vue 實例作為一個事件總線中心(central event bus)
1.新建bus.js文件
import Vue from 'vue'
export default new Vue()
2.引用bus.js
import bus from './bus'
3.在組件 A 的 methods 方法中觸發(fā)事件
bus.$emit('START_LOADING')
bus.$emit('FINISH_LOADING')
4.在組件 B 中監(jiān)聽事件
export default {
data () {
return {
loading: 0 // 全局加載loading
}
},
mounted () {
this.initConfig()
},
// ...
methods: {
initConfig () {
bus.$on('START_LOADING', () => {
this.loading ++
})
bus.$on('FINISH_LOADING', () => {
this.loading --
})
}
}
}
在復(fù)雜場景中仪缸,應(yīng)該考慮使用專門的狀態(tài)管理模式(==>快速理解Vuex)
原文:
快速掌握vue組件間的通訊