Vue組件間通信方法總結(jié)(父子組件、兄弟組件及祖先后代組件間)
前言
除了使用 Vuex 方法外,vue 提供了各種各樣的組件間通信的方案。文章整理一下父子組件、兄弟組件、祖先后代組件間是如何通信的。 💬
🌊 父子組件通信
props 和 $emit 父子組件通信
子組件有時(shí)需要與父組件進(jìn)行溝通,溝通的方式就是子組件 emit 事件,父組件通過監(jiān)聽這個(gè)事件來做進(jìn)一步動(dòng)作。而父組件與子組件通信則使用 props
假設(shè)這里有一個(gè)父組件并引入了一個(gè)子組件 my-comp:
<my-comp v-for="msg in msgs" :key="msg.id" :msg="msg"></my-comp>
父組件有一系列 msg 數(shù)據(jù)需要通過子組件渲染,將 msg 作為 prop 傳遞給子組件即可:
import MyComp from '@/components/MyComp.vue' export default { name: 'home', components: { MyComp }, data () { return { msgs: [{ id: 1, data: 'hello js' }, { id: 2, data: 'css world' }, { id: 3, data: 'animated style' }] } } }
我們通過點(diǎn)擊子組件每一項(xiàng)觸發(fā)一個(gè)事件,父組件監(jiān)聽這個(gè)事件去動(dòng)態(tài)改變子組件的 color 樣式,這就是父組件監(jiān)聽子組件事件,事件處理函數(shù)可以從子組件傳遞值給父組件:
<my-comp v-for="msg in msgs" :key="msg.id" :msg="msg" :colored="colored" @handle-change-color="handleChangeColor"></my-comp>
首先增加一個(gè)事件 handle-change-color 當(dāng)這個(gè)事件被觸發(fā)時(shí)修改名為 color 的 data,然后將 colored 通過 props 傳入到子組件:
import MyComp from '@/components/MyComp.vue' export default { name: 'home', components: { // 注冊(cè)組件 MyComp }, data () { return { colored: false, // 狀態(tài) msgs: [{ id: 1, data: 'hello js' }, { id: 2, data: 'css world' }, { id: 3, data: 'animated style' }] } }, methods: { handleChangeColor () { this.colored = !this.colored // 監(jiān)聽事件動(dòng)態(tài)改變 colored } // handleChangeColor (param) { // 子組件觸發(fā)的事件可能包含參數(shù) } }
然后編輯子組件:
<div> <div @click="handleClick" :style="{color}"> {{msg.id}} - {{msg.data}} ⭕ </div> </div>
首先渲染數(shù)據(jù),并監(jiān)聽 click 點(diǎn)擊事件,當(dāng)點(diǎn)擊觸發(fā)事件處理函數(shù) handleClick
export default { name: 'MyComp', computed: { color () { // color 為樣式 return this.colored ? 'red' : 'black' // 根據(jù)父組件傳入的 props 動(dòng)態(tài)修改樣式 } }, props: ['msg', 'colored'], methods: { handleClick (e) { this.$emit('handle-change-color') // 使用 $emit 方法觸發(fā)父組件 handle-change-color 事件 // this.$emit('handler', 'param') // 還可以給事件傳遞參數(shù) } } }
子組件接收 colored 父組件傳遞來的 prop,返回一個(gè)計(jì)算后的屬性 color,根據(jù) colored 返回不同樣式。handleClick 處理當(dāng)子組件元素被點(diǎn)擊時(shí) $emit 派發(fā)父組件的 handle-change-color 事件
效果如下:
父組件 $children 操作子組件
使用 $children 操作子組件。如上述例子中,colored 被定義在父組件中,可以將其移動(dòng)到子組件中,并在父組件通過 $children 訪問到子組件:
<template> <div @click="handleClick" class="home"> <my-comp v-for="msg in msgs" :key="msg.id" :msg="msg"></my-comp> </div> </template>
handleClick 事件被放置在 div 中
import MyComp from '@/components/MyComp.vue' export default { // ... data () { return { msgs: [{ // ... }] } }, methods: { handleClick () { this.$children.forEach(child => { child.$data.colored = !child.$data.colored // 逐一控制子組件的 $data }) } } }
在子組件中不需要 $emit 事件,只需維護(hù)一個(gè) data:
export default { name: 'MyComp', data () { return { colored: false // colored 狀態(tài) } }, computed: { color () { return this.colored ? 'red' : 'black' } }, props: ['msg'] }
子組件 $parent 訪問父組件
子組件可通過 $parent 來修改父組件的 $data,因此 colored 定義在父組件中。
<template> <div class="home"> <my-comp v-for="msg in msgs" :key="msg.id" :msg="msg" :colored="colored"></my-comp> </div> </template>
通過 prop 傳遞 colored 參數(shù)給子組件
import MyComp from '@/components/MyComp.vue' export default { name: 'home', components: { MyComp }, data () { return { colored: false, // 父組件維護(hù)一個(gè) colored 狀態(tài) msgs: [{ // ... }] } } }
父組件定義 colored 狀態(tài)
<template> <div> <div @click="handleClick" :style="{color}"> {{msg.id}} - {{msg.data}} ⭕ </div> </div> </template>
子組件渲染 msg 并監(jiān)聽 click 事件
export default { // ... props: ['msg', 'colored'], methods: { handleClick (e) { this.$parent.$data.colored = !this.$parent.$data.colored } } }
通過 $parent 訪問父組件,并修改 $data 狀態(tài)
非父子組件通信
中央事件總線
我們可以使用使用中央事件總線來處理非父子組件間的通信
具體步驟是創(chuàng)建一個(gè) Vue 實(shí)例,然后 $on 監(jiān)聽事件,$emit 來派發(fā)事件
// src/eventBus.js import Vue from 'vue' export default new Vue()
首先創(chuàng)建并導(dǎo)出一個(gè) Vue 實(shí)例
import bus from '@/eventbus' export default { // ... methods: { handleClick (e) { bus.$emit('change-color') } } }
后代元素 $emit 觸發(fā) eventBus 的事件
import bus from '@/eventbus' export default { // ... mounted () { bus.$on('change-color', () => { this.colored = !this.colored }) } }
祖先元素 $on 方法監(jiān)聽 eventBus 的事件
provide/inject
適用于祖先和后代關(guān)系的組件間的通信,祖先元素通過 provide 提供一個(gè)值,后代元素則通過 inject 獲取到這個(gè)值。這個(gè)值默認(rèn)是非響應(yīng)的,如果是對(duì)象那么則是響應(yīng)式的:
export default { name: 'home', provide () { return { colored: this.colored // 依賴于 data } }, components: { MyComp }, data () { return { colored: { // 必須為對(duì)象 value: false }, msgs: [{ // ...
首先通過 provide 對(duì)外提供一個(gè) colored,這個(gè)屬性依賴于 data 中的 colored,該變量必須為一個(gè)對(duì)象,才是響應(yīng)式的。
⚠️ 必須為一個(gè)對(duì)象
methods: { handleChangeColor () { this.colored.value = !this.colored.value } }
祖先組件監(jiān)聽事件或其他途徑去修改 data 改變狀態(tài)。
export default { name: 'MyComp', inject: ['colored'], // inject colored computed: { color () { return this.colored.value ? 'red' : 'black' // do more... } }, // ...
后代組件通過 inject 獲取到祖先組件提供的對(duì)象,根據(jù)對(duì)象做進(jìn)一步動(dòng)作。
$root 直接訪問根組件
根據(jù)官方的文檔,我們可以通過 $root 來直接訪問到 Vue 實(shí)例
比方說將數(shù)據(jù)存儲(chǔ)在 Vue 實(shí)例中:
// src/main.js new Vue({ data () { return { // 在這里?。? colored: false } }, router, store, render: h => h(App) }).$mount('#app')
然后我們?cè)谄渌鱾€(gè)組件中都能夠使用:
export default { name: 'MyComp', // ... mounted () { console.log(this.$root) // 直接訪問到根組件 }, // ... }
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
element-ui 限制日期選擇的方法(datepicker)
本篇文章主要介紹了element-ui 限制日期選擇的方法(datepicker),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-05-05vue實(shí)現(xiàn)學(xué)生錄入系統(tǒng)之添加刪除功能
本文給大家?guī)硪粋€(gè)小案例基于vue實(shí)現(xiàn)學(xué)生錄入系統(tǒng)功能,代碼簡(jiǎn)單易懂非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2018-07-07基于Vue中this.$options.data()的this指向問題
這篇文章主要介紹了基于Vue中this.$options.data()的this指向問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03Vue 全家桶實(shí)現(xiàn)移動(dòng)端酷狗音樂功能
這篇文章主要介紹了Vue 全家桶實(shí)現(xiàn)移動(dòng)端酷狗音樂功能,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-11-11vue使用Print.js打印頁(yè)面樣式不出現(xiàn)的解決
這篇文章主要介紹了vue使用Print.js打印頁(yè)面樣式不出現(xiàn)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10詳解windows下vue-cli及webpack 構(gòu)建網(wǎng)站(二)導(dǎo)入bootstrap樣式
這篇文章主要介紹了詳解windows下vue-cli及webpack 構(gòu)建網(wǎng)站(二)導(dǎo)入bootstrap樣式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06element日期選擇器el-date-picker樣式圖文詳解
最近寫的項(xiàng)目里面有一個(gè)功能是日期選擇功能,第一反應(yīng)是使用element里面的el-date-picker組件,下面這篇文章主要給大家介紹了關(guān)于element日期選擇器el-date-picker樣式的相關(guān)資料,需要的朋友可以參考下2022-09-09