提示:组件通信
什么是组件通信
组件通信,就是组件与组件之间的数据传递
想用其他组件的数据–>组件通信
一、父子通信
1.父组件通过props将数据传递给子组件
2.子组件利用$emit通知父组件修改更新
1.步骤
(1)父传子
父组件通过props将数据传递给子组件
- 给子组件以添加属性的方式传值
- 子组件内部通过props接收
- 子组件将接收的数据在模板中直接使用
(2)子传父
子组件利用$emit通知父组件,进行修改更新
- $emit触发事件,给父组件发送消息通知
- 父组件监听事件
- 父组件提供处理函数,形参中获取参数
二、非父子通信
1.event bus 事件总线
2.provide & inject
1.event bus 事件总线
创建一个都能访问到的事件总线(空的Vue实例)
步骤
- 在src文件夹中创建新文件夹utils,在文件夹utils创建EventBus.js文件
代码如下:
import Vue from 'vue'
const Bus = new Vue()
export default Bus
- 在要使用的组件中导入EventBus.js,不在APP.vue和Main.js中导入
- 信息接收方,用Bus.$on()监听Bus实例的事件,并接收数据
代码如下:
<template>
<div class="one">
<span>今天天气怎么样?</span>
<div>{{ msgIfon }}</div>
</div>
</template>
<script>
import Bus from '../untils/EventBus.js'
export default {
created() {
Bus.$on('send', (msg) => {
this.msgIfon = msg
})
},
data() {
return {
msgIfon:''
}
}
}
</script>
- 信息发送方,用Bus.$emit()触发Bus实例的事件
代码如下:
<template>
<div class="two">我是发布方
<button @click="sendMsg">发送通知</button>
</div>
</template>
<script>
import Bus from '../untils/EventBus.js'
export default {
methods: {
sendMsg() {
Bus.$emit('send','晴转多云')
}
}
}
</script>
2.provide & inject
跨层级共享数据----子孙后代
复杂类型(响应式,推荐)
简单数据类型 (非响应式)
共享的时候,通常把它包成一个对象,以复杂类型的方式去共享
步骤
- 父组件只需用provide()提供数据,不需要给子组件绑定属性
代码如下:
<template>
<div id="app">我是父组件App.vue
<SonA></SonA>
<SonB></SonB>
</div>
</template>
<script>
import SonA from './components/SonA.vue'
import SonB from './components/SonB.vue'
export default {
components: {
SonA,
SonB
},
provide() {
return {
today: this.today,
obj:this.todoList
}
},
data() {
return {
today: ['周六'],
todoList:['吃饭','睡觉','玩游戏','打扫卫生']
}
}
}
</script>
- 子孙后代组件,用inject接收数据
代码如下:
孙子组件GrandSon.vue
<template>
<div class="grandson">我是GrandSon组件--{{ today }}--要做--{{ obj }}</div>
</template>
<script>
export default {
inject:['today','obj']
}
</script>
<style scoped>
.grandson{
width: 100px;
height: 50px;
font-size: 10px;
margin: 15px;
border: 1px solid #000;
}
</style>
子组件SonA.vue
<template>
<div class="son1">我是SonA组件--未用inject接收值
<GrandSon></GrandSon>
</div>
</template>
<script>
import GrandSon from './GrandSon.vue'
export default {
components: {
GrandSon
}
}
</script>
<style scoped>
.son1 {
width: 150px;
height: 100px;
border: 1px solid red;
margin: 20px;
}
</style>
子组件SonB.vue
<template>
<div class="son2">我是SonB组件-今天:{{ today }}--要做:{{ obj }}</div>
</template>
<script>
export default {
inject:['today','obj']
}
</script>
<style scoped>
div{
width: 150px;
height: 100px;
border: 1px solid green;
margin: 20px;
}
</style>