使用Vue也有很長一段時間,可是一直以來都沒對其組件之間的通訊作一個總結,此次就藉此總結一下。
父子組件之間的通訊
1)props和$emit
父組件經過props將數據下發給props,子組件經過$emit來觸發自定義事件來通知父組件進行相應的操做
具體代碼以下:
```
// 父組件
<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)ref
ref 被用來給元素或子組件註冊引用信息。引用信息將會註冊在父組件的 $refs 對象上。若是在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;若是用在子組件上,引用就指向組件實例
具體代碼以下:
```
// 父組件
<template>
<div>
<h1>父組件</h1>
<button @click="update">修改子組件</button>
<Children ref="child"></Children>
</div>
</template>
<script>
import Children from './children';
export default {
name: 'parent',
components: {
Children
},
methods: {
update() {
this.$refs.child.msg = '被修改了';
}
}
}
</script>
// 子組件
<template>
<div>
<h3>{{msg}}</h3>
</div>
</template>
<script>
export default {
data() {
return {
msg: '子組件'
}
}
}
</script>
```
4)自定義事件的v-model
https://cn.vuejs.org/v2/guide/components-custom-events.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E7%BB%84%E4%BB%B6%E7%9A%84-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的數據和自定義事件傳遞給組件C,就可使用$attrs和$listeners。
vm.$attrs: 當一個組件沒有聲明任何 prop 時(沒有在props聲明屬性),這裏會包含全部父做用域的綁定 ,而且能夠經過 v-bind="$attrs" 傳入內部組件
vm.$listeners: 包含了父做用域中的 (不含 .native 修飾器的) v-on 事件監聽器。它能夠經過 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: '下發數據',
test: '123'
}
},
components: {
Children
},
methods: {
changeMsg() {
this.msg = '修改後的數據';
}
}
}
</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">修改數據</button>
</div>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
change() {
this.$emit('changeMsg')
}
}
}
</script>
```
```
非父子組件之間的通訊
經過中央事件總線來進行通訊
經過新建一個Vue事件的bus對象,而後經過bus.$emit來觸發事件,bus.$on監聽觸發的事件。使用中央事件總線時,須要在手動清除它,否則它會一直存在,本來只執行一次的操做,將會執行屢次。
具體代碼以下:
```
// 父組件
<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">增長數量</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>數量: {{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 建立的bus
import Vue from 'vue';
export const BUS = new Vue({
})
```
經過vuex來進行數據管理,具體內容見vuex官網
若是有什麼不對的地方,或者還有什麼方法我沒有寫到,但願你們能夠提出來,謝謝。