VUE的开发像搭积木,由一个一个的组件搭建而成,那么组件之间的关系就要十分清晰,有什么关系呢?他们又如何通信呢?
组件之间的关系大致上有两种: 1、父子关系(一个) 2、兄弟
回到正题,明确了各组件的关系呢,我们就可以去探究他们如何通信了。通信的种类要多于关系的种类。大致上分为三种:1、父子通信 2、兄弟通信 3、跨层级通信
一、首先我们谈论父子之间如何通信
(1)、父向子传递信息 例如:告诉儿子快去吃饭。 通过 props
//父组件
<template>
<div id="app">
<son v-bind:message="why"></son>//子组件
</div>
</template>
<script>
import Users from "./components/Users"
export default {
name: 'father',
data(){
return{
why:'快去吃饭'
}
},
components:{
"users":Users
}
}
//son子组件
<template>
<div class="hello">
<h4>{{}}</h4>
</div>
</template>
<script>
export default {
name: 'son',
props:{
message:{ //message 就是父组件在子组件模版中传的的数据
type:String,//对数据效验 类型
required:true//是否强制
}
}
}
</script>
(2)、子向父传递信息 例如:告诉父亲我知道了 通过$emit('监听','数据')
//父组件
<template>
<div id="app">
<h4>{{why}}</h4>
<son v-on:callback="todo"></son>//子组件 //设置callback监听
</div>
</template>
<script>
import Users from "./components/Users"
export default {
name: 'father',
data(){
return{
why:''
},
mehtods:{
todo(e){
this.why = e
}
},
components:{
"users":Users
}
}
<template>
<div id="app">
<button @click="todo"></button>
</div>
</template>
<script>
import Header from "./components/Header"
export default {
name: 'son',
data(){
return{
message:'我吃了'
}
},
methods:{
todo(){ //方法
this.$emit('cellback',message);//通知父组件的监听
}
},
}
</script>
二、接下来讲一下兄弟组件的通信 例如:A告诉B我们一起去吃饭。 通过eventbus来通信
创建一个enentbus.js
// eventbus.js
import Vue from 'vue'
export const EventBus = new Vue()//公开这个对象
在需要通信的组件中引入 这个对象 例如:
A组件
<!-- A.vue -->
<template>
<button @click="sendMsg()">-</button>
</template>
<script>
import { EventBus } from "../eventbus.js"; //导入相同的eventbus
export default {
methods: {
sendMsg() {
EventBus.$emit("why", '我们一起去吃饭吧!');//通知名为why的监听事件发送我们一起去吃饭吧!
}
}
};
</script>
B组件
<!-- B.vue -->
<template>
<p>{{msg}}</p>
</template>
<script>
import { EventBus } from "../eventbus.js"; //导入共同的中间件
export default {
data(){
return {
msg: ''
}
},
mounted() {//vue的周期函数 dom挂载结束
EventBus.$on("why", (msg) => {//监听why的事件线
// A发送来的消息 更新导p标签
this.msg = msg;
});
}
};
</script>
三、跨层级通信 比如:爷爷告诉孙子你来我家吃饭吧。
1、爷爷组件中
//App.vue中定义变量,引入子组件
<template>
<div>
<son></son>
</div>
</template>
<script>
import son from './components/son.vue'
export default {
name: "y",
data(){
return{
message:'孙子,来我家吃饭吧。'
}
},
provide() {//提供数据
return{
why: this.message //why 不会挂在vue实例上 需要自己声名在data中
}
},
components:{
son
}
}
</script>
2、儿子组件中
//./components/Son.vue 子组件中引入孙子组件调用父组件数据
<template>
<div>
{{msg}}
<groundSon></groundSon>
</div>
</template>
<script>
import groundSon from './components/groundSon.vue'
export default {
name: "son",
inject: ['why'],//提取数据
data() {
return {
msg: this.why
}
},
components: {
groundSon
}
}
</script>
3、孙子组件中
// ./components/groundSon.vue 孙子组件中引用它爷爷的数据
<template>
<div>
{{msg}}
</div>
</template>
<script>
export default {
name: "groundSon",
inject: ['why'],
data() {
return {
msg: this.why
}
}
}
</script>
跨层级通信的特点:爷爷提供的信息不仅儿子可以访问,而且孙子也可以拿到。
注意:只有引用类型是响应式的