目录
概述
props配置项-回调函数实现
自定义事件实现
事件总线实现
消息订阅与发布实现
概述
在组件化编程中,组件间的通信是重要的,我们可以有四种方式实现组件间的通信。
分别是:函数回调,自定义事件,事件总线和消息订阅与发布。
本篇博客将使用App组件和Student组件完成组件间通讯通信的演示。
props配置项-回调函数实现
父组件(App)给子组件(Student)传递数据
父组件想要给子组件传递数据,只需要父组件在使用子组件的位置书写传递数据即可,子组件使用props配置项接收。
App组件(父组件)
<template>
<div id="app">
<Studnet :name="name"></Studnet>
</div>
</template>
<script>
import Studnet from './components/Studnet.vue'
export default {
name: 'App',
data(){
return {
name:"Tom"
}
},
components: {
Studnet
}
}
</script>
Studnet组件(子组件)
<template>
<div>
<button @click="printAppData">点击</button>
</div>
</template>
<script>
export default {
name:"Student",
props:["name"],
methods:{
printAppData(){
console.log(this.name);
}
}
}
</script>
当我们点击按钮后,查看控制台
子组件给父组件传递数据
我们在实现子组件给父组件传递数据的时候,要是还是想要使用props直接传递的话显然不合适。
因为props只能父组件在调用子组件时传递数据。
虽然我们不能直接传递数据,但是我们可以换一个思路,那就是我们在父组件向子组件传递回调函数,当子组件在合适的时机调用传入的回调函数时可以设置函数参数,那么我们在父组件的函数实现就可以获取到调用函数时传入的参数数据。
App组件(父组件)
<template>
<div id="app">
<!--传递回调函数-->
<Studnet :name="name" :getData="getData"/>
</div>
</template>
<script>
import Studnet from './components/Studnet.vue'
export default {
name: 'App',
data(){
return {
name:"Tom"
}
},
components: {
Studnet
},
methods:{
getData(age){
console.log("获取到子组件的参数:",age);
}
}
}
</script>
Student组件(子组件)
<template>
<div>
<button @click="printAppData">点击(父向子组件传数据)</button>
<button @click="getData(age)">点击(子向父组件传数据)</button>
</div>
</template>
<script>
export default {
name:"Student",
// 接收回调函数
props:["name","getData"],
data(){
return{
age:18
}
},
methods:{
printAppData(){
console.log("接收到父组件传递的数据是:",this.name);
},
}
}
</script>
<style>
</style>
自定义事件实现
子组件给父组件传递数据
我们可以在父组件中给子组件绑定一个自定义事件,子组件在合适的时机执行此自定义事件的时候传递一些数据即可。
App组件(父组件)
<template>
<div id="app">
<!-- 给Student组件(子组件)绑定一个myEvent自定义事件 -->
<Studnet @myEvent="myEvent"/>
</div>
</template>
<script>
import Studnet from './components/Studnet.vue'
export default {
name: 'App',
data(){
return {
}
},
components: {
Studnet
},
methods:{
// 当自定义事件被触发时,执行此函数获取调用函数时的参数
myEvent(name){
console.log("获取到子组件的参数:",name);
}
}
}
</script>
Student组件(子组件)
<template>
<div>
<button @click="clcikHandle">点击触发自定义事件</button>
</div>
</template>
<script>
export default {
name:"Student",
// 接收回调函数
data(){
return{
name:"Tom"
}
},
methods:{
clcikHandle(){
this.$emit("myEvent",this.name)
}
}
}
</script>
当我们点击按钮,控制台打印:
在其中我们给子组件绑定自定义事件还有另一种方式:
<Studnet ref="studnetComp"/>
通过ref属性获取到节点,再给节点绑定事件即可
this.$refs.studnetComp.$on("自定义事件",处理函数)
解绑自定义事件
this.$off(["事件名称"])
事件总线实现
事件总线:实现任意组件间的通信,上方的回调函数或者是自定义事件的方式实现的组件通信都有缺陷,当我们想要第一级组件和第三级组件间的通信时,就需要逐层传递,又或者是兄弟组件间通信是实现不了的,所以出现了事件总线的事件。
其原理就是我们找出一个公共可访问区域,在此区域绑定自定义事件,当想要给某组件传递数据时,只需要执行该组件在公共区域放置的自定义事件并传递参数即可。
例如下图解,当我们B组件想要给A组件传递数据时,只需要A组件在公共区域绑定自定义事件,并书写事件处理函数接收参数,当B组件想传递数据的时候,找到A组件在公共区域绑定的自定义事件执行并传入参数,那么A组件中的事件处理函数将接收到传来的参数,那么我们就可以实现B组件给A组件传递数据了。
此公共区域可以为任意组件服务,实现任意组件的数据通信,所以我们称此公共区域叫做事件总线,因为它控制着所有组件的事件绑定。
此公共位置就是在VUE原型对象上绑定,想要在VUE原型对象上绑定事件,并且可以使用原型上的方法,那么我们就只能考虑实例对象vc或vm。
兄弟组件传递数据 (Student组件给Student1组件传递数据)
1.给Vue原型对象上添加$bus属性,值为vm (安装全局事件总线)
new Vue({
render: h => h(App),
beforeCreate(){
Vue.prototype.$bus = this
}
}).$mount('#app')
2.Student1组件在总线上绑定事件
export default {
name:Student1,
mounted(){
this.$bus.$on("myEvent",this.printInfo)
},
methods:{
printInfo(_,args){
console.log("获取到的参数为:",args);
}
}
3.Studnet组件在合适的时机执行studnet1上绑定的自定义事件并传入参数作为数据。
// 当点击页面上某个按钮时调用自定义事件并传入参数
clcikHandle(){
this.$bus.$emit("myEvent",this.name)
}
消息订阅与发布实现
此方式也可以实现任意组件间的通信,跟事件总线的实现方式很像。
消息发布与订阅是一种思想
订阅者:需要数据的组件
发布者:提供数据的组件
实现此思想的JS库有许多,在此使用pubsub-js做演示
使用步骤:
需求:Student组件给Student1组件传递数据
1.导入pubsub-js
2.订阅信息(Studnet1组件操作)
导入pubsub库
import pubsub from "pubsub-js"
// 发布订阅消息,当有对应消息发布时会传递数据进来
pubsub.subscribe("消息名",消息处理函数)
3.信息发布(Studnet组件操作)
导入pubsub库
import pubsub from "pubsub-js"
// 发布消息,对应的订阅了此消息名的函数会执行并且接收到此参数
pubsub.publish("消息名",参数)