开发中经常会遇到组件间需要进行通信的场景,在这里做一个详细的归纳。
父子组件之间的通信
最常见的是父子组件之间的通信,也是通信中较简单的一类。通信分为两种情况:【父组件向子组件通信】和【子组件向父组件通信】
子组件接收父组件的值-props
父组件-communication.vue
<template>
<div class="father">
这是父组件<br />
<!-- v-bind(:)前者自定义名称便于子组件调用,后者要传递的数据名-->
<child :fatherData="fatherData"></child>
</div>
</template>
<script>
import child from '../components/child.vue';
export default {
components:{
child
},
data() {
return{
fatherData:'我是父组件',
}
}
}
</script>
子组件-child.vue
<template>
<div class="child">
这是子组件<br/>
<div>接受父组件的值---({{ fatherData }})</div>
</div>
</template>
<script>
export default {
props:['fatherData'],
}
</script>
子组件改变父组件中的值-this.$emit
子组件-child.vue
<template>
<div class="child">
这是子组件<br/>
<el-button @click="changeFatherData">改变父组件的值</el-button>
</div>
</template>
<script>
export default {
data(){
return{
childMsg:'我是子组件'
}
},
methods:{
changeFatherData(){
this.$emit('getChildData',this.childMsg)
}
}
}
</script>
父组件-communication.vue
<template>
<div class="father">
这是父组件<br />
<div>接收子组件的值---({{ childData }})</div>
<!-- v-model(@)-->
<child @getChildData = "getChildData" ></child>
</div>
</template>
<script>
import child from '../components/child.vue';
export default {
components:{
child
},
data() {
return{
childData:""
}
},
methods:{
getChildData(value) {
this.childData = value
}
}
}
</script>
父组件调用子组件中的方法-this.$refs
子组件-child.vue
methods:{
childMethods(){
console.log("子组件中的方法被调用啦!");
}
}
父组件-communication.vue
<template>
<div class="father">
这是父组件<br />
<el-button @click="changeChildData">调用子组件中的方法</el-button>
<child ref="child" ></child>
</div>
</template>
<script>
import child from '../components/child.vue';
export default {
components:{
child
},
methods:{
changeChildData(){
this.$refs.child.childMethods()
}
}
}
</script>
子组件调用父组件中的方法
$parent
父组件-communication.vue
methods:{
fatherMethods() {
console.log("父组件被调用啦!")
}
}
子组件-child.vue
<template>
<div class="child">
这是子组件<br/>
<el-button @click="changeFatherData">调用父组件中的方法</el-button>
</div>
</template>
<script>
export default {
methods:{
changeFatherData(){
this.$parent.fatherMethods()
}
}
}
</script>
$emit
父组件-communication.vue
<template>
<div class="father">
这是父组件<br />
<child @fatherMethods="fatherMethods" ></child>
</div>
</template>
methods:{
fatherMethods() {
console.log("父组件被调用啦!")
}
}
子组件-child.vue
<template>
<div class="child">
这是子组件<br/>
<el-button @click="changeFatherData">调用父组件中的方法</el-button>
</div>
</template>
<script>
export default {
props:['fatherMethods'],
methods:{
changeFatherData(){
this.$emit('fatherMethods')
},
}
}
</script>
兄弟组件之间的通信
父组件作为桥梁
传递值--emit+props
场景:子组件2接收子组件1中的值
子组件1-child1.vue
<template>
<div class="child1">
这是子组件1<br/>
<el-button @click="changeChild2">给子组件2传值</el-button>
</div>
</template>
<script>
export default {
props:['getChildData'],
data(){
return{
childMsg:'我是子组件1'
}
},
methods:{
changeChild2(){
this.$emit('getChildData',this.childMsg)
}
}
}
</script>
父组件-communication.vue
<template>
<div class="father">
这是父组件<br />
<div class="component">
<child1 @getChildData = "getChild1Data" ></child1>
<child2 :child1Data="child1Data"></child2>
</div>
</div>
</template>
<script>
import child1 from '../components/child1.vue';
import child2 from '../components/child2.vue';
export default {
components:{
child1,
child2
},
data() {
return{
child1Data:""
}
},
methods:{
getChild1Data(value) {
this.child1Data = value
}
}
}
</script>
子组件2-child2.vue
<template>
<div class="child2">
这是子组件2<br/>
<div>接受子组件1的值---({{ child1Data }})</div>
</div>
</template>
<script>
export default {
props:['child1Data'],
}
</script>
传递方法--ref+emit
场景:子组件2调用子组件1中的方法
子组件1-child1.vue
methods:{
child1Method(){
console.log("子组件1中的方法被调用啦!");
}
}
}
父组件-communication.vue
<template>
<div class="father">
这是父组件<br />
<div class="component">
<child1 ref="child1" ></child1>
<child2 @getChild1Method="getChild1Method"></child2>
</div>
</div>
</template>
<script>
import child1 from '../components/child1.vue';
import child2 from '../components/child2.vue';
export default {
components:{
child1,
child2
},
methods:{
getChild1Method() {
this.$refs.child1.child1Method()
}
}
}
</script>
子组件2-child2.vue
<template>
<div class="child2">
这是子组件2<br/>
<el-button @click="getChild1Methods">调用子组件1中的方法</el-button>
</div>
</template>
<script>
export default {
props:['getChild1Method'],
data(){
return{
childMsg:'我是子组件'
}
},
methods:{
getChild1Methods(){
this.$emit('getChild1Method');
}
}
}
</script>
eventBus
场景:子组件2接收子组件1中的数据
/utils/eventBus.js
import Vue from 'vue'
const eventBus = new Vue()
export default eventBus
/main.js
import eventBus from './utils/eventBus'
//这个方式可以在任何组件里直接用 this.$EventBus 调用
Vue.prototype.$eventBus = eventBus
子组件1-child1.vue
<template>
<div class="child1">
这是子组件1<br/>
<el-button @click="child1Method">给子组件2传值</el-button>
</div>
</template>
export default {
data(){
return {
num:1
}
},
methods:{
child1Method(){
this.$eventBus.$emit('getNum',this.num);
}
}
}
</script>
子组件2-child2.vue
<template>
<div class="child2">
这是子组件2<br/>
<div>接受子组件1的值---({{ num }})</div>
</div>
</template>
<script>
export default {
data(){
return{
num:null
}
},
mounted() {
this.$eventBus.$on('getNum',(num)=>{
this.num = num
console.log(num);
})
},
beforeDestroy(){
this.$eventBus.$off('getdNum')
}
}
</script>