詳解Vue組件之間通信的七種方式
使用Vue也有很長一段時間,但是一直以來都沒對其組件之間的通信做一個總結,這次就借此總結一下。
父子組件之間的通信
1)props和$emit
父組件通過props將數(shù)據(jù)下發(fā)給props,子組件通過$emit來觸發(fā)自定義事件來通知父組件進行相應的操作
具體代碼如下:
```
// 父組件
<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: 父實例,如果當前實例有的話
vm.$children: 獲取當前實例的直接直接子組件,需要注意的是$children并不保證順序,也不是響應式的
具體代碼如下:
```
// 父組件的代碼
<template>
<div>
<h3>{{title}}</h3>
<button @click="amend">在父組件中修改子組件的標題</button>
<Children />
</div>
</template>
<script>
import Children from './children.vue';
export default {
data() {
return {
title: '父組件'
}
},
components: {
Children
},
methods: {
amend() {
this.$children[0].title = '修改后的子組件標題';
}
}
}
</script>
// 子組件的代碼
<template>
<div>
<h3>{{title}}</h3>
<button @click="amend">在子組件中修改父組件的標題</button>
</div>
</template>
<script>
export default {
data() {
return {
title: '子組件'
}
},
methods: {
amend() {
this.$parent.title = '修改后的父組件標題';
}
}
}
</script>
```
3)自定義事件的v-model
```
// 父組件
<template>
<div>
標題:<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,允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,并在起上下文關系成立的時間里始終生效
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: '父組件的標題'
}
},
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('子組件修改標題');
}
},
components: {
Grandson
}
}
</script>
// 孫組件
<template>
<div>
<button @click="changeAttr">修改祖先組件的屬性</button>
</div>
</template>
<script>
export default {
inject: ['updateTitle'],
methods: {
changeAttr() {
this.updateTitle('孫組件修改標題');
}
}
}
</script>
```
2)$attrs和$listeners
組件A下面有一個組件B,組件B下面有一個組件C,如果想將組件A的數(shù)據(jù)和自定義事件傳遞給組件C,就可以使用$attrs和$listeners。
vm.$attrs: 當一個組件沒有聲明任何 prop 時(沒有在props聲明屬性),這里會包含所有父作用域的綁定 ,并且可以通過 v-bind="$attrs" 傳入內部組件
vm.$listeners: 包含了父作用域中的 (不含 .native 修飾器的) v-on 事件監(jiān)聽器。它可以通過 v-on="$listeners" 傳入內部組件。
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>
```
```
非父子組件之間的通信
通過中央事件總線來進行通信
通過新建一個Vue事件的bus對象,然后通過bus.$emit來觸發(fā)事件,bus.$on監(jiān)聽觸發(fā)的事件。使用中央事件總線時,需要在手動清除它,不然它會一直存在,原本只執(zhí)行一次的操作,將會執(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>第一個組件</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>第二個組件</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來進行數(shù)據(jù)管理,具體內容見vuex官網(wǎng)
如果有什么不對的地方,或者還有什么方法我沒有寫到,希望大家可以提出來,謝謝。
總結
以上所述是小編給大家介紹的Vue組件之間通信的七種方式,希望對大家有所幫助,如果大家有任何疑問歡迎給我留言,小編會及時回復大家的!
- Vue組件通信的幾種實現(xiàn)方法
- Vue中Table組件Select的勾選和取消勾選事件詳解
- Vue 實現(xiàn)手動刷新組件的方法
- vue組件文檔(.md)中如何自動導入示例(.vue)詳解
- vue-cli3.0+element-ui上傳組件el-upload的使用
- Vue.js的動態(tài)組件模板的實現(xiàn)
- vue實現(xiàn)一個炫酷的日歷組件
- Vue實現(xiàn)調節(jié)窗口大小時觸發(fā)事件動態(tài)調節(jié)更新組件尺寸的方法
- 使用vue.js在頁面內組件監(jiān)聽scroll事件的方法
- 如何寫好一個vue組件,老夫的一年經(jīng)驗全在這了(推薦)
相關文章
vue從后臺渲染文章列表以及根據(jù)id跳轉文章詳情詳解
這篇文章主要給大家介紹了關于vue從后臺渲染文章列表以及根據(jù)id跳轉文章詳情的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-12-12
一步步教你用Vue.js創(chuàng)建一個組件(附代碼示例)
組件(Component)是Vue.js最強大的功能之一,組件可以擴展HTML元素,封裝可重用的代碼,下面這篇文章主要給大家介紹了關于如何一步步用Vue.js創(chuàng)建一個組件的相關資料,需要的朋友可以參考下2022-12-12
vue.js過濾器+ajax實現(xiàn)事件監(jiān)聽及后臺php數(shù)據(jù)交互實例
這篇文章主要介紹了vue.js過濾器+ajax實現(xiàn)事件監(jiān)聽及后臺php數(shù)據(jù)交互,結合實例形式分析了vue.js前臺過濾器與ajax后臺數(shù)據(jù)交互相關操作技巧,需要的朋友可以參考下2018-05-05

