詳解Vue組件之間通信的七種方式
使用Vue也有很長一段時(shí)間,但是一直以來都沒對(duì)其組件之間的通信做一個(gè)總結(jié),這次就借此總結(jié)一下。
父子組件之間的通信
1)props和$emit
父組件通過props將數(shù)據(jù)下發(fā)給props,子組件通過$emit來觸發(fā)自定義事件來通知父組件進(jìn)行相應(yīng)的操作
具體代碼如下:
```
// 父組件
<template>
<div>
<h3>props和$emit</h3>
<Children v-on:changeMsg="changeMsg" :msg="msg"/>
</div>
</template>
<script>
import Children from './children';
export default {
data() {
return {
msg: '傳遞的值'
}
},
components: {
Children
},
methods: {
changeMsg(val) {
this.msg = val;
}
}
}
</script>
// 子組件
<template>
<div>
<h3 @click="notify">{{msg}}</h3>
</div>
</template>
<script>
export default {
data(){
return {
}
},
props: ['msg'],
methods: {
notify() {
this.$emit('changeMsg', '修改后的');
}
}
}
</script>
```
2)vm.$parent和vm.$children
vm.$parent: 父實(shí)例,如果當(dāng)前實(shí)例有的話
vm.$children: 獲取當(dāng)前實(shí)例的直接直接子組件,需要注意的是$children并不保證順序,也不是響應(yīng)式的
具體代碼如下:
```
// 父組件的代碼
<template>
<div>
<h3>{{title}}</h3>
<button @click="amend">在父組件中修改子組件的標(biāo)題</button>
<Children />
</div>
</template>
<script>
import Children from './children.vue';
export default {
data() {
return {
title: '父組件'
}
},
components: {
Children
},
methods: {
amend() {
this.$children[0].title = '修改后的子組件標(biāo)題';
}
}
}
</script>
// 子組件的代碼
<template>
<div>
<h3>{{title}}</h3>
<button @click="amend">在子組件中修改父組件的標(biāo)題</button>
</div>
</template>
<script>
export default {
data() {
return {
title: '子組件'
}
},
methods: {
amend() {
this.$parent.title = '修改后的父組件標(biāo)題';
}
}
}
</script>
```
3)自定義事件的v-model
```
// 父組件
<template>
<div>
標(biāo)題:<input type="text" v-model="mymessage"><br />
<Children v-model="mymessage" />
</div>
</template>
<script>
import Children from './children.vue';
export default {
data() {
return {
mymessage: '名字',
}
},
components: {
Children
}
}
</script>
// 子組件
<template>
<div>
<input type="text" :value="mymessage" @input="changeValue">
</div>
</template>
<script>
export default {
model: {
prop: 'mymessage',
event: 'input'
},
props: ['mymessage'],
methods: {
changeValue(event){
this.$emit('input', event.target.value);
}
}
}
</script>
```
祖先組件和其子孫組件通信
1)provide/inject
provide/inject,允許一個(gè)祖先組件向其所有子孫后代注入一個(gè)依賴,不論組件層次有多深,并在起上下文關(guān)系成立的時(shí)間里始終生效
https://cn.vuejs.org/v2/api/#provide-inject
具體代碼如下:
```
// 父組件
<template>
<div>
<h3>{{title}}</h3>
<Children />
</div>
</template>
<script>
import Children from './children.vue';
export default {
data() {
return {
title: '父組件的標(biāo)題'
}
},
provide() {
return {
updateTitle: this.updateTitle
}
},
methods: {
updateTitle(title) {
this.title = title;
}
},
components: {
Children
}
}
</script>
// 子組件
<template>
<div>
<button @click="changeAttr">修改父組件的屬性</button>
<Grandson />
</div>
</template>
<script>
import Grandson from './grandson.vue';
export default {
data() {
return {
}
},
inject: ['updateTitle'],
methods: {
changeAttr() {
this.updateTitle('子組件修改標(biāo)題');
}
},
components: {
Grandson
}
}
</script>
// 孫組件
<template>
<div>
<button @click="changeAttr">修改祖先組件的屬性</button>
</div>
</template>
<script>
export default {
inject: ['updateTitle'],
methods: {
changeAttr() {
this.updateTitle('孫組件修改標(biāo)題');
}
}
}
</script>
```
2)$attrs和$listeners
組件A下面有一個(gè)組件B,組件B下面有一個(gè)組件C,如果想將組件A的數(shù)據(jù)和自定義事件傳遞給組件C,就可以使用$attrs和$listeners。
vm.$attrs: 當(dāng)一個(gè)組件沒有聲明任何 prop 時(shí)(沒有在props聲明屬性),這里會(huì)包含所有父作用域的綁定 ,并且可以通過 v-bind="$attrs" 傳入內(nèi)部組件
vm.$listeners: 包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器。它可以通過 v-on="$listeners" 傳入內(nèi)部組件。
https://cn.vuejs.org/v2/api/#vm-attrs
具體代碼如下:
```
// 父組件
<template>
<div>
<Children :msg="msg" v-on:changeMsg="changeMsg"/>
</div>
</template>
<script>
import Children from './children';
export default {
data() {
return {
msg: '下發(fā)數(shù)據(jù)',
test: '123'
}
},
components: {
Children
},
methods: {
changeMsg() {
this.msg = '修改后的數(shù)據(jù)';
}
}
}
</script>
// 子組件
<template>
<div>
<Grandson v-bind="$attrs" v-on="$listeners"/>
</div>
</template>
<script>
import Grandson from './grandson';
export default {
components: {
Grandson
}
}
</script>
// 孫組件
```
<template>
<div>
<h3>{{$attrs.msg}}</h3>
<button @click="change">修改數(shù)據(jù)</button>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
change() {
this.$emit('changeMsg')
}
}
}
</script>
```
```
非父子組件之間的通信
通過中央事件總線來進(jìn)行通信
通過新建一個(gè)Vue事件的bus對(duì)象,然后通過bus.$emit來觸發(fā)事件,bus.$on監(jiān)聽觸發(fā)的事件。使用中央事件總線時(shí),需要在手動(dòng)清除它,不然它會(huì)一直存在,原本只執(zhí)行一次的操作,將會(huì)執(zhí)行多次。
具體代碼如下:
```
// 父組件
<template>
<div>
<One />
<Two />
</div>
</template>
<script>
import One from './one.vue';
import Two from './two.vue';
export default {
data() {
return {
}
},
components: {
One,
Two
}
}
</script>
// one組件
<template>
<div>
<h3>第一個(gè)組件</h3>
<button @click="add">增加數(shù)量</button>
</div>
</template>
<script>
import {BUS} from './index.js';
export default {
data() {
return {
}
},
methods: {
add() {
BUS.$emit('add');
}
},
beforeDestory() {
BUS.$off('add');
}
}
</script>
// two組件
<template>
<div>
<h3>第二個(gè)組件</h3>
<h3>數(shù)量: {{num}}</h3>
</div>
</template>
<script>
import {BUS} from './index.js';
export default {
data() {
return {
num: 1
}
},
mounted() {
BUS.$on('add', () => {
this.num += 1;
})
},
beforeDestroy() {
BUS.$off('add');
}
}
</script>
// index.js 創(chuàng)建的bus
import Vue from 'vue';
export const BUS = new Vue({
})
```
通過vuex來進(jìn)行數(shù)據(jù)管理,具體內(nèi)容見vuex官網(wǎng)
如果有什么不對(duì)的地方,或者還有什么方法我沒有寫到,希望大家可以提出來,謝謝。
總結(jié)
以上所述是小編給大家介紹的Vue組件之間通信的七種方式,希望對(duì)大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會(huì)及時(shí)回復(fù)大家的!
- Vue組件通信的幾種實(shí)現(xiàn)方法
- Vue中Table組件Select的勾選和取消勾選事件詳解
- Vue 實(shí)現(xiàn)手動(dòng)刷新組件的方法
- vue組件文檔(.md)中如何自動(dòng)導(dǎo)入示例(.vue)詳解
- vue-cli3.0+element-ui上傳組件el-upload的使用
- Vue.js的動(dòng)態(tài)組件模板的實(shí)現(xiàn)
- vue實(shí)現(xiàn)一個(gè)炫酷的日歷組件
- Vue實(shí)現(xiàn)調(diào)節(jié)窗口大小時(shí)觸發(fā)事件動(dòng)態(tài)調(diào)節(jié)更新組件尺寸的方法
- 使用vue.js在頁面內(nèi)組件監(jiān)聽scroll事件的方法
- 如何寫好一個(gè)vue組件,老夫的一年經(jīng)驗(yàn)全在這了(推薦)
相關(guān)文章
Vue.js項(xiàng)目部署到服務(wù)器的詳細(xì)步驟
這篇文章給大家介紹了Vue.js項(xiàng)目部署到服務(wù)器的詳細(xì)步驟,既然是部署到服務(wù)器,肯定是需要一個(gè)云的。具體思路步驟大家可以參考下本文2017-07-07
Vue中使用?Aplayer?和?Metingjs?添加音樂插件的方式
這篇文章主要介紹了Vue中使用?Aplayer?和?Metingjs?添加音樂插件,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
reactive readonly嵌套對(duì)象轉(zhuǎn)換功能實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了reactive readonly嵌套對(duì)象轉(zhuǎn)換功能實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
Vue項(xiàng)目保持element組件同行,設(shè)置組件不自動(dòng)換行問題
這篇文章主要介紹了Vue項(xiàng)目保持element組件同行,設(shè)置組件不自動(dòng)換行問題。具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
VUE 直接通過JS 修改html對(duì)象的值導(dǎo)致沒有更新到數(shù)據(jù)中解決方法分析
這篇文章主要介紹了VUE 直接通過JS 修改html對(duì)象的值導(dǎo)致沒有更新到數(shù)據(jù)中解決方法,結(jié)合實(shí)例形式詳細(xì)分析了VUE使用JS修改html對(duì)象的值導(dǎo)致沒有更新到數(shù)據(jù)的原因與解決方法,需要的朋友可以參考下2019-12-12

