组件间通信
1. props 传递函数
是一种组件间消息传递的方法,适用于
子 ===>>> 父
父组件:声明函数,并传递给子组件
<template>
<MySon :sendMsg1="sendMsg1" :sendMsg2="sendMsg2"/>
</template>
<script>
import MySon from "@/components/Son.vue";
export default {
name: "MyFather",
components: {MySon},
methods: {
sendMsg1(msg1) {
console.log(msg1)
},
sendMsg2(msg2) {
console.log(msg2)
}
}
}
</script>
子组件:调用回调函数,并传递参数,使得父组件接收到数据
<template>
<h1>555</h1>
</template>
<script>
export default {
name: "MySon",
props: ['sendMsg1', 'sendMsg2'],
mounted() {
this.sendMsg1(1)
this.sendMsg2(2)
}
}
</script>
2. 自定义事件【不推荐】
是一种组件间消息传递的方法,适用于
子 ===>>> 父
组件上面也可以绑定原生的 DOM 事件,需要使用
native
修饰符,如:<Demo @click.native="show"></Demo>
,此时在 Dome 组件的身上有了clcik
事件,点击组件的时候调用回调函数show
父组件:使用子组件,并给子组件绑定自定义事件
方法一
<template>
<div id="root">
<!-- @事件名称="事件回调函数的名称,实际上是函数的引用" -->
<MyCom
v-on:sendmsg1="sendmsg3"
@sendmsg2="sendmsg1"
@sendmsg3.once="sendmsg2"
/>
</div>
</template>
<script>
import MyCom from "@/components/MyCom.vue";
export default {
name: 'App',
components: { MyCom },
methods: {
sendmsg1(data) {
console.log(data)
},
sendmsg2(data) {
console.log(data)
}
}
}
</script>
方法二
<script>
mounted() {
// 可以触发多次的自定义事件
// - this.$refs.demo.$on('事件名称', 事件回调函数)
// - 回调函数可以在 methods 中
// - 也可以使用匿名函数,但是必须使用箭头函数,因为 this 指向的问题
this.$refs.demo.$on('sendmsg1', this.sendmsg1)
this.$refs.demo.$on('sendmsg2', this.sendmsg2)
// 只可以触发一次的自定义事件
this.$refs.demo.$once('sendmsg2', this.sendmsg2)
}
</script>
子组件:手动触发已绑定的自定义事件,并在适当的时机解除自定义事件
<template>
<h1>hello</h1>
</template>
<script>
export default {
name: "MyCom",
methods: {
MyFun() {
// 手动触发自定义事件
this.$emit('sendDeleteOkTodo')
this.$emit('sendUpdateAll', newValue)
},
},
beforeDestroy() {
// 手动解绑指定的自定义事件
this.$off('sendDeleteOkTodo')
// 手动解绑全部的自定义事件
// this.$off()
}
}
</script>
3. 全局事件总线
是一种组件间消息传递的方法,适用于
任意组件 ===>>> 任意组件
本质是一个中间对象,绑定了自定义事件,然后所有的组件均可以访问到该中间对象,并且该对象必须可以使用
$on()
、$once()
、$emit()
方法去操作事件
main.js
:定义全局的事件总线【定义中间对象】
//引入Vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = false
new Vue({
render: h => h(App),
beforeCreate() {
// 给 Vue 的原型对象绑定一个中间对象,该对象是 Vue 实例 vm
// - Vue原型对象可以被所有的组件访问
// - Vue实例vm可以绑定、解绑自定义事件
// - $bus 是自定义的名称
Vue.prototype.$bus = this
}
}).$mount('#app')
父组件:绑定自定义事件【接收数据】
<template>
<MySon/>
</template>
<script>
import MySon from "@/components/Son.vue";
export default {
name: "MyFather",
components: {MySon},
mounted() {
this.$bus.$on('sendMsg1', (data) => {
console.log(data)
})
this.$bus.$on('sendMsg2', (data) => {
console.log(data)
})
},
beforeDestroy() {
this.$off()
}
}
</script>
子组件:手动调用自定义事件【传递数据】
<template>
<h1>hello,world!</h1>
</template>
<script>
export default {
name: "MySon",
mounted() {
this.$bus.$emit('sendMsg1', {'id': '001', 'name': 'tom'})
this.$bus.$emit('sendMsg2', 'hello')
}
}
</script>
4. 消息订阅与发布
是一种组件间消息传递的方法,适用于
任意组件 ===>>> 任意组件
【更推荐使用全局事件总线】
安装第三方库
npm i pubsub-js
父组件:引入第三方库,并订阅消息,然后再合适的位置取消订阅
<template>
<MySon/>
</template>
<script>
// 引入第三方库
import pubsub from 'pubsub-js'
import MySon from "@/components/Son.vue";
export default {
name: "MyFather",
components: {MySon},
mounted() {
// 订阅消息,生成一个唯一 id,保持到 this 身上,以便于取消订阅
this.id1 = pubsub.subscribe('sendMsg1', (data) => {
console.log(data)
})
this.id2 = pubsub.subscribe('sendMsg2', (data) => {
console.log(data)
})
},
beforeDestory() {
// 取消订阅
pubsub.unsubscribe(this.id1)
pubsub.unsubscribe(this.id2)
}
}
</script>
子组件:发布消息,每一次的消息发布,都会生成一个唯一的消息 id,下次取消订阅时,指明该 id 即可
<template>
<h1>hello,world!</h1>
</template>
<script>
// 引入第三方库
import pubsub from 'pubsub-js'
export default {
name: "MySon",
mounted() {
// 发布消息
pubsub.publish('sendMsg1', {id: '001',name: 'tom',age: 56})
// 发布消息
pubsub.publish('sendMsg2', 'hello')
}
}
</script>