Vue如何實(shí)現(xiàn)組件間通信
1. 父子間通信
最常見的就是父子之間的通信,通信是雙向的數(shù)據(jù)傳遞。
1.1 父組件 --> 兒子組件
父組件向兒子組件傳遞數(shù)據(jù)的方式就是 通過(guò) Prop 向子組件傳遞數(shù)據(jù)。
//child.vue
<template>
<div>
我是兒子,我收到來(lái)自父親的數(shù)據(jù)為 {{value}}
</div>
</template>
<script>
export default {
props:{
value: String
}
}
//App.vue
<template>
<div id="app">
<Child :value="x" />
</div>
</template>
<script>
import Child from './components/Child'
export default {
data(){
return {
x: 'hi,child'
}
},
components:{
Child
}
}
</script>
1.2 兒子組件 --> 父組件
兒子組件向父組件傳遞數(shù)據(jù)的方式就是通過(guò)子組件內(nèi) $emit 觸發(fā)自定義事件,子組件使用時(shí) v-on 綁定監(jiān)聽自定義事件。
這里的 v-on 事件通信是在子組件使用時(shí)作為子組件的事件屬性自動(dòng)進(jìn)行監(jiān)聽的。
因此兒子組件向父組件傳遞數(shù)據(jù),依賴于子組件使用時(shí)的自定義事件屬性。
//child.vue
<template>
<div>
我是兒子,我收到來(lái)自父親的數(shù)據(jù)為 {{value}}
<button @click="sayHi">
向父組件打招呼
</button>
</div>
</template>
<script>
export default {
props:{
value: String
},
methods:{
sayHi(){
this.$emit('sayHi','hi,parent!');
}
}
}
</script>
//App.vue
<template>
<div id="app">
我是父組件,我收到子組件傳來(lái)的數(shù)據(jù)為 {{y}}
<Child :value="x" @sayHi="y = $event"/>
</div>
</template>
<script>
import Child from './components/Child'
export default {
data(){
return {
x: 'hi,child',
y: ''
}
},
components:{
Child
}
}
</script>

2. 爺孫間通信
爺孫間通信,可以使用兩次 v-on 通信,爺爺爸爸通信,然后爸爸兒子通信。
也可使用下方的任意組件間通信的方式。
3. 任意組件間通信
任意組件間通信就不再區(qū)分是 A 向 B 通信,還是 B 向 A 通信,而是通用的方式,誰(shuí)想發(fā)送數(shù)據(jù)就使用對(duì)應(yīng)的 API 發(fā)送數(shù)據(jù),誰(shuí)想要接收什么數(shù)據(jù),就使用對(duì)應(yīng)的 API 接收。
任意組件間通信有兩種方式,一種是使用 EventBus 發(fā)布訂閱模式通信,一種是使用 Vuex 通信。
3.1 EventBus
EventBus ,從字面意思理解就是事件公交車,所有觸發(fā)的事件傳遞的數(shù)據(jù)都從前門上車保存到公交車上,然后通過(guò)監(jiān)聽對(duì)應(yīng)事件提供的出口讓對(duì)應(yīng)的事件數(shù)據(jù)下車。
EventBus,實(shí)際意思是發(fā)布和訂閱模式,就是誰(shuí)想把數(shù)據(jù)傳遞出去,就要通過(guò)觸發(fā)自定義事件的 API 進(jìn)行數(shù)據(jù)的發(fā)布;誰(shuí)需要接收該數(shù)據(jù)信息的,就通過(guò)事件監(jiān)聽的 API 進(jìn)行數(shù)據(jù)的監(jiān)聽,一旦檢測(cè)到監(jiān)聽的數(shù)據(jù)發(fā)布出來(lái),就會(huì)接收,這就是數(shù)據(jù)的訂閱。
EventBus 通信方式最重要是搞明白發(fā)布和訂閱的接口 API,在 Vue 中,Vue 實(shí)例有提供兩個(gè)接口,即 $emit 和 $on ,因此可以新創(chuàng)建一個(gè)空的 Vue 實(shí)例,來(lái)獲得這兩個(gè)接口。
const eventBus = new Vue(); eventBus.$emit(eventName, […args]) //發(fā)布事件 eventBus.$on(event, callback) //訂閱事件
實(shí)例如下:
// eventBus.js import Vue from 'vue' export const eventBus = new Vue();
//child
<template>
<div>
我是兒子,我收到來(lái)自父親的數(shù)據(jù)為 <strong>{{value}}</strong>
<button @click="sayHi">
向父組件打招呼
</button>
<button @click="sibling">
向兄弟組件打招呼
</button>
</div>
</template>
<script>
import {eventBus} from '../eventBus.js'
export default {
props:{
value: String
},
methods:{
sayHi(){
this.$emit('sayHi','hi,parent!');
},
sibling(){
eventBus.$emit('sibling','hi,brother');
}
}
}
</script>
<style scoped>
strong{
color: red;
}
</style>
//sibling
<template>
<div>
我是兄弟組件,我收到來(lái)自兒子組件的數(shù)據(jù)信息為 <strong>{{x}}</strong>
</div>
</template>
<script>
import {eventBus} from '../eventBus.js'
export default {
data(){
return {
x: ''
}
},
mounted(){
eventBus.$on('sibling', (msg)=>{
this.x = msg;
})
}
}
</script>
<style scoped>
strong{
color: green;
}
</style>
//parent
<template>
<div id="app">
我是父組件,我收到子組件傳來(lái)的數(shù)據(jù)為 <strong>{{y}}</strong>
<Child :value="x" @sayHi="y = $event"/>
<Sibling></Sibling>
</div>
</template>
<script>
import Child from './components/Child'
import Sibling from './components/Sibling'
export default {
data(){
return {
x: 'hi,child',
y: ''
}
},
components:{
Child,
Sibling
}
}
</script>
<style scoped>
strong{
color: blue;
}
</style>

關(guān)于 EventBus 這部分,可能存在這樣一個(gè)疑問(wèn),既然 Vue 實(shí)例中都有 $emit 和 $on,為什么不直接用 this.$emit 觸發(fā)事件, this.$on 接收事件呢?還非得要額外一個(gè)空實(shí)例 eventBus = new Vue() 。那是因?yàn)椋琕ue 中每個(gè)組件都是一個(gè)單獨(dú)的 Vue 實(shí)例,你在這個(gè) Vue 實(shí)例中觸發(fā)該實(shí)例的 emit 事件,另外一個(gè)實(shí)例的 on 事件是接收不到的,不在一輛公交車上,怎么能進(jìn)行事件通信呢?因此就必須要一個(gè)公共的公交車,也就是事件總線。
上述實(shí)例中的 eventBus 的使用方法是局部的 eventBus,誰(shuí)要用到 eventBus 要自己手動(dòng)引入。也可以將 eventBus 做成全局的,比如掛在 vue 的原型上。
//main.js
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
Vue.prototype.$eventBus = new Vue();//添加這句,一定要在下方的 new Vue 前。
new Vue({
render: h => h(App),
}).$mount('#app')
//child
sibling(){
this.$eventBus.$emit('sibling','hi,brother');
}
//sibling
mounted(){
this.$eventBus.$on('sibling', (msg)=>{
this.x = msg;
})
}
除了上述的添加屬性到 Vue 原型的方式外,還可以使用 Object.defineProperty() 為 Vue 原型添加屬性。
import Vue from 'vue'
import App from './App.vue'
Vue.config.productionTip = false
let eventBus = new Vue()
Object.defineProperty(Vue.prototype,'$eventBus',{
get(){
return eventBus
}
})
new Vue({
render: h => h(App),
}).$mount('#app')
3.2 Vuex
Vue 組件間的通信也可使用專門為 vue.js 應(yīng)用程序開發(fā)的狀態(tài)管理模式:Vuex。Vuex 的使用比較復(fù)雜,詳細(xì)可見 Vuex 博客。Vuex 適用于大型的復(fù)雜的 Vue 項(xiàng)目的狀態(tài)管理。對(duì)于一些中小型的應(yīng)用程序,可以根據(jù) Vuex 的原理自定義 store 模式進(jìn)行狀態(tài)管理,vue 自定義狀態(tài)管理,可詳見 Vue 簡(jiǎn)單狀態(tài)管理—store模式 博客。
無(wú)論是 Vuex 還是 自定義 store模式 ,其實(shí)現(xiàn)組件間通信的原理都是通過(guò)共享數(shù)據(jù)的方式實(shí)現(xiàn)的。組件間使用相同的數(shù)據(jù)源,當(dāng)一個(gè)組件改變數(shù)據(jù)時(shí),另一個(gè)組件依賴的數(shù)據(jù)源也就改變了。
以上就是Vue如何實(shí)現(xiàn)組件間通信的詳細(xì)內(nèi)容,更多關(guān)于Vue組件間通信的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue2項(xiàng)目中如何使用clipboard復(fù)制插件
這篇文章主要介紹了vue2項(xiàng)目中如何使用clipboard復(fù)制插件方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07
Vue自定義指令實(shí)現(xiàn)按鈕級(jí)的權(quán)限控制的示例代碼
在Vue中可以通過(guò)自定義指令來(lái)實(shí)現(xiàn)按鈕權(quán)限控制,本文主要介紹了Vue自定義指令實(shí)現(xiàn)按鈕級(jí)的權(quán)限控制的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-05-05
移動(dòng)端底部導(dǎo)航固定配合vue-router實(shí)現(xiàn)組件切換功能
經(jīng)常遇到這樣的需求,移動(dòng)端中的導(dǎo)航并不是在頂部也不是在底部,而是在最底部且是固定的,當(dāng)我們點(diǎn)擊該導(dǎo)航項(xiàng)時(shí)會(huì)切換到對(duì)應(yīng)的組件。這篇文章主要介紹了移動(dòng)端底部導(dǎo)航固定配合vue-router實(shí)現(xiàn)組件切換功能,需要的朋友可以參考下2019-06-06
Vue 實(shí)現(xiàn)分頁(yè)與輸入框關(guān)鍵字篩選功能
這篇文章主要介紹了Vue 實(shí)現(xiàn)分頁(yè)+輸入框關(guān)鍵字篩選功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
Vue3?中路由Vue?Router?的使用實(shí)例詳解
vue-router是vue.js官方給出的路由解決方案,能夠輕松的管理SPA項(xiàng)目中組件的切換,這篇文章主要介紹了Vue3?中路由Vue?Router?的使用,需要的朋友可以參考下2023-02-02
Vue使用new?Blob()實(shí)現(xiàn)不同類型的文件下載功能
這篇文章主要給大家介紹了關(guān)于Vue使用new?Blob()實(shí)現(xiàn)不同類型的文件下載功能的相關(guān)資料,在Vue項(xiàng)目中,經(jīng)常用Blob二進(jìn)制進(jìn)行文件下載功能,需要的朋友可以參考下2023-07-07
elementUI el-input 只能輸入正整數(shù)驗(yàn)證的操作方法
這篇文章主要介紹了elementUI el-input 只能輸入正整數(shù)驗(yàn)證,本文給大家詳細(xì)講解對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-11-11

