组件通信,就是组件与组件之间的数据传递。
组件方案:
一.父子通信:props&$emit
1.父组件通过props将数据传递给子组件
2.子组件利用$emit通知父组件修改更新
1.父组件传递数据,并监听事件
<template>
<div class="App">
<div>{{msg}}</div>
<div>{{str}}</div>
<!-- 组件通信:子传父 -->
<!-- 4.给父组件->进行消息监听 -->
<BaseOne :title="msg" @changemsg="handleChange"></BaseOne>
</div>
</template>
<script>
import BaseOne from "./components/BaseOne";
export default {
// 2.设置传值数据
data() {
return {
msg: "白马传媒!",
str:'黑马传媒'
};
},
components: {
BaseOne
},
methods: {
// 4.进行监听函数处理
handleChange(value) {
this.str = value;
}
},
};
</script>
<style>
.App{
border: 1px solid #000;
}
</style>
2.子组件利用props接收数据,利用$emit创建事件并携带新数据
<template>
<div class="son">我是子组件{{title}}
<!-- 1.创建事件 向父组件发送消息 -->
<button @click="etit">修改</button>
</div>
</template>
<script>
export default {
props: ["title"],
methods:{
// 2.创建发送消息函数
etit(){
// 3.通过$emit,向父组件发送消息通知
this.$emit('changemsg','黑马帕帕')
}
}
};
</script>
<style scoped>
span {
cursor: pointer;
}
.son{
border: 1px solid #000;
margin: 10px;
}
</style>
二.非父子通信
爷孙组件通信:provide&inject
provide&inject作用:跨层级共享数据
1.创建根组件,利用provide让孙子接收数据
<template>
<div class="box">
<div>我是爷爷{{ color }}</div>
<button @click="changecolor"></button>
<BaseA></BaseA>
</div>
</template>
<script>
import BaseA from "./components/BaseA";
export default {
components: {
BaseA,
},
// 利用provide,让孙子级的组件可以接收到数据
provide() {
return {
color: this.color,//非响应式数据
Obj: this.obj,//响应式数据
};
},
data() {
return {
color: "pink",
obj: {
name: "小明",
age: 20,
},
};
},
methods: {
changecolor() {
this.color = 'yellow'
}
}
};
</script>
<style scoped>
.box {
border: 1px solid #000;
width: 500px;
height: 500px;
}
</style>
2.创建子组件,利用inject接收父组件数据
<template>
<div class="box1">
<div>我是爸爸{{color}}-{{Obj.name}}-{{Obj.age}}</div>
<BaseB></BaseB>
</div>
</template>
<script>
import BaseB from "./BaseB";
export default {
components: {
BaseB,
},
inject:["color","Obj"]
};
</script>
<style >
.box1 {
border: 1px solid #000;
width: 100%;
text-align: center;
background-color: pink;
height: 200px;
margin-top: 50px;
}
</style>
3.利用inject接收爷组件的数据
<template>
<div>我是儿子 {{ color }}-{{Obj.name}}-{{Obj.age}}</div>
</template>
<script>
export default {
// 利用inject 可以接收爷爷级组件的数据
inject: ["color","Obj"],
};
</script>
<style scoped>
div {
border: 1px solid #000;
background-color: red;
width: 100%;
height: 100px;
}
</style>
注意:修改爷组件中的简单数据类型的数据,数据发生变化,子孙组件视图不会发生变化,不支持简单类型的数据响应式。复杂类型支持响应式数据视图变化。
事件总线:eventbus
作用:非父子组件之间,进行建议简易消息传递。(复杂场景->Vuex)
1.在utils下创建事件总线
// 1.创建一个都能访问到的事件总线(空的vue实例)
import vue from 'vue'
const Bus = new vue()
export default Bus
2.发送方创建事件
<template>
<div>
<span>我是BaseB</span>
<button @click="clickSend">点击</button>
</div>
</template>
<script>
import Bus from "../utils/EventBus";
export default {
methods: {
// 2.发送方创建Bus事件
clickSend() {
Bus.$emit('sentMsg',"今日天气晴")
}
}
}
</script>
<style scoped>
div {
width: 300px;
height: 300px;
border: 1px solid #000;
background-color: pink;
}
</style>
3.接收方监听事件
<template>
<div>我是BaseA
<span>{{msg}}</span>
</div>
</template>
<script>
import Bus from "../utils/EventBus";
export default {
created() {
// 3.在接收方进行监听Bus事件
Bus.$on("sentMsg", (msg) => {
this.msg=msg
})
},
data(){
return {
msg:''
}
}
}
</script>
<style scoped>
div {
width: 300px;
height: 300px;
border: 1px solid #000;
background-color: pink;
}
</style>
4.在app.vue中导入使用
<template>
<div>
<BaseA></BaseA>
<BaseB></BaseB>
<BaseC></BaseC>
</div>
</template>
<script>
import BaseA from "./components/BaseA";
import BaseB from "./components/BaseB";
import BaseC from "./components/BaseC";
export default {
components: {
BaseA,
BaseB,
BaseC,
},
};
</script>
<style>
</style>