什么是组件通信------就是指组件与组件之间的数据传递
组件的数据是独立的,无法直接访问其他组件的数据
想用其他组件的数据------组件通信
组件关系分类
各部分完整代码及行内注释都在模块下面
1.父子关系
props和$emit
1.父组件通过props将数据传递给子组件
第一步:给子组件以 添加属性 的方式传递
第二步:子组件内部通过 props:[] 接收
第三步:直接使用props的值
2.子组件利用$emit通知父组件修改更新
第一步:$emit触发事件,给父组件发送消息通知
第二步:父组件监听事件
第三步:提供处理函数,形参中获取参数
注意名字不要写错了
完整代码参考这里
App.vue
<template>
<div id="app" class="fat">
<span>我是父组件 App</span>
<!-- 父传子第一步 :
给子组件以添加属性的方式传递-->
<!-- 子向父传递,2.父组件监听事件 -->
<!-- @changeTitle="随便起一个复合命名规范的名字就可以" -->
<Son :title="myTitle" @changeTitle="learnChange"></Son>
</div>
</template>
<script>
// 在export外面导入.vue文件
import Son from "./components/Son.vue";
export default {
name: 'App',
components: {
Son,
},
data() {
return {
myTitle:'天使神'
}
},
methods:{
//子向父传递,3.提供处理函数,形参中获取参数
learnChange(title){
this.myTitle=title;
}
}
}
</script>
<style scoped>
.fat{
border: 3px solid blue;
margin:30px;
padding: 30px;
}
</style>
Son.vue
<template>
<div class="son">
<span>我是子组件 Son ---</span>
<!-- 父传子第三步:直接使用props的值 -->
{{ title }}
<br><br>
<button @click="changeTitle">修改title值</button>
</div>
</template>
<script>
export default {
name:'Son-Child',
// 父传子第二步:子组件内部通过 props:[] 接收
props:['title'],
methods:{
changeTitle(){
// 子向父传递,发出请求
//1.$emit触发事件,给父组件发送消息通知
this.$emit('changeTitle','修罗神才是最牛的')
}
}
}
</script>
<style scoped>
.son{
border: 3px solid red;
margin: 20px;
padding: 20px;
}
</style>
2.非父子关系
1>provide&inject
provide&inject作用:跨层级共享数据
1.父组件provide提供数据
2.子/孙组件inject取值使用
具体代码的注释
完整代码参考这里
App.vue
<template>
<div class="app">
我是APP组件
<button @click="change">修改数据</button>
<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 {
// 简单类型 是非响应式的
color: this.color,
// 复杂类型 是响应式的
userInfo: this.userInfo,
}
},
data() {
return {
color: 'blue',
userInfo: {
name: 'MoMoCi',
age: 18,
},
}
},
methods: {
change() {
this.color = 'red'
this.userInfo.name = 'Chemo'
},
},
}
</script>
<style>
.app {
width: 400px;
padding: 20px;
border: 3px solid #000;
border-radius: 6px;
margin: 10px;
}
</style>
SonA.vue
<template>
<div class="SonA">
子组件A
<GrandSon></GrandSon>
</div>
</template>
<script>
import GrandSon from '../components/GrandSon.vue'
export default {
components: {
GrandSon
},
}
</script>
<style scoped>
.SonA{
height: 100px;
width: 300px;
margin: 30px;
padding: 20px;
border: 3px solid black;
}
</style>
SonB.vue
<template>
<div class="SonB">
子组件B
</div>
</template>
<script>
export default {
}
</script>
<style scoped>
.SonB{
height: 100px;
width: 300px;
margin: 30px;
padding: 20px;
border: 3px solid black;
}
</style>
GrandSon.vue
<template>
<div class="grandson">
孙子组件
<br>
{{ color }} -{{ userInfo.name }} - {{ userInfo.age }}
</div>
</template>
<script>
export default {
inject: ['color', 'userInfo'],
}
</script>
<style scoped>
.grandson{
width: 200px;
height: 40px;
padding: 10px;
border: 3px solid red;
}
</style>
2>eventbus
非父子组件之间,进行简易消息传递。
1.创建一个都能访问的事件总线(空Vue实例)utils/EventBus.js
2.A组件(接收方),监听Bus实例的事件
3.B组件(发送方),触发Bus实例的事件
具体代码的注释
完整代码参考这里
utils/EventBus.js
// 1.创建一个都能访问到的事件总线(空的 vue 实例)
import Vue from 'vue'
const Bus = new Vue()
export default Bus
App.vue
<template>
<div>
<BaseA></BaseA>
<BaseB></BaseB>
<BaseC></BaseC>
</div>
</template>
<script>
import BaseA from './components/BaseA.vue'
import BaseB from './components/BaseB.vue'
import BaseC from './components/BaseC.vue'
export default {
components: {
BaseA,BaseB,BaseC
}
}
</script>
BaseA.vue
<template>
<div class="base-a">
我是A组件 (接收者)
<p>{{ msg }}</p>
</div>
</template>
<script>
import Bus from '../utils/EventBus'
export default {
created(){
// 2.在A组件(接收方),进行监听Bus的事件(订阅消息)
Bus.$on('sendMsg',(msg) => {
console.log(msg);
this.msg = msg;
})
},
data(){
return{
msg:''
}
}
}
</script>
<style>
.base-a{
box-sizing: border-box;
height: 200px;
width: 400px;
margin: 30px;
padding: 20px;
font-size: 30px;
border: 5px solid black;
}
</style>
BaseB.vue
<template>
<div class="base-b">
我是B组件 (发送者)
<button @click="send">发送讯息</button>
</div>
</template>
<script>
import Bus from '../utils/EventBus'
export default {
methods:{
send(){
// 3.B组件(发送方),进行监听事件的方式传递参数(发布消息)
Bus.$emit('sendMsg','咚巴拉呀咚巴咚巴拉')
}
}
}
</script>
<style lang="less">
.base-b{
box-sizing: border-box;
height: 200px;
width: 400px;
margin: 30px;
padding: 20px;
font-size: 30px;
border: 5px solid black;
button{
width: 90px;
height: 30px;
font-size: 16px;
}
}
</style>
BaseC.vue
<template>
<div class="base-c">
我是C组件 (接收者)
<p>{{ msg }}</p>
</div>
</template>
<script>
import Bus from '../utils/EventBus'
export default {
created(){
// 2.在C组件(接收方),进行监听Bus的事件(订阅消息)
Bus.$on('sendMsg',(msg) => {
console.log(msg);
this.msg = msg;
})
},
data(){
return{
msg:''
}
}
}
</script>
<style>
.base-c{
box-sizing: border-box;
height: 200px;
width: 400px;
margin: 30px;
padding: 20px;
font-size: 30px;
border: 5px solid black;
}
</style>