前言
父子组件通信
1、使用props和$emit父子组件相互通信;
2、父组件$children操作子组件;
3、子组件$parent访问父组件;
非父子组件通信
1、使用中间事件总线(eventbus)来处理非父子组件间的通信;
2、祖先元素通过provide提供数据,后代通过inject获取该数据;
3、使用$attrs和$listenerss实现祖孙组件通信;
4、$root直接访问根组件;
接下来介绍下非父子组件通信中的Event Bus和Provide Inject
Event Bus
效果图

直接撸代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Event Bus 组件通信</title>
<script src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<com-a></com-a>
<com-b></com-b>
<com-c></com-c>
</div>
<template id="coma">
<div>
<h3>A组件:{{msg}}</h3>
<button @click="sendToC">A将msg发送给C组件</button>
</div>
</template>
<template id="comb">
<div>
<h3>B组件:{{msg}}</h3>
<button @click="sendToC">B将msg发送给C组件</button>
</div>
</template>
<template id="comc">
<div>
<h3>C组件:{{msg}}</h3>
</div>
</template>
<script>
//中央事件总线
var Event = new Vue();
var A= {
template:'#coma',
data(){
return {
msg:'A传递给C的msg'
}
},
methods:{
sendToC(){
Event.$emit('data-a',this.msg);
}
}
};
var B= {
template:'#comb',
data(){
return {
msg:'B传递给C的msg'
}
},
methods:{
sendToC(){
Event.$emit('data-b',this.msg);
}
}
};
var C= {
template:'#comc',
data(){
return {
msg:''
}
},
mounted(){
Event.$on('data-a',msg=>{
this.msg = msg;
});
Event.$on('data-b',msg=>{
this.msg = msg;
})
}
};
let vm = new Vue({
el:'#app',
components:{
'com-a':A,
'com-b':B,
'com-c':C
}
});
</script>
</body>
</html>
provide inject
效果图

代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>provide--inject组件通信方式</title>
<script src="../node_modules/vue/dist/vue.js"></script>
</head>
<body>
<div id="app">
<h1>
{{projectName}}
<br/>
{{appName}}
<br/>
{{timeFlag}}
<br/>
</h1>
<Parent/>
</div>
<script>
const Child = {
inject:['appName','projectName'],
template:`<div>
{{projectName}}
<br/>
{{appName}}此时Parent修改了appName
</div>`
};
const Parent = {
inject:['appName','timeFlag','projectName'],
provide(){
return{
appName:this.appName + '父级接收上级传来数据处理后的appName',
}
},
components:{
Child,
},
template:`<div>
{{projectName}}
<br/>
{{appName}}
<br/>
{{timeFlag}}
<br/>
<Child/>
</div>`
}
const projectName = '跨级组件通信';
let vm = new Vue({
el:'#app',
components:{
Parent
},
provide(){
return{
projectName:this.projectName,
appName:this.appName,
timeFlag:this.timeFlag
}
},
data:{
projectName,
appName:'这是app名称',
now:Date.now()
},
computed:{
timeFlag(){
return this.now;
}
},
created(){
setInterval(()=>{
this.now = Date.now();
},1000)
}
});
</script>
</body>
</html>