[Vue] Part XII communication between components (custom event, global event bus, message subscription and Publication) is very important
12. Communication between components (custom event, global event bus, message subscription and Publication)
12.1 component customization events
-
Function: it can realize the communication between child components = = > parent components
-
Suppose: A: parent component, B: sub component. When B wants to transmit data to a, a needs to bind a custom event to B in advance (the callback of the event should be left in a), trigger the custom event in B and write the parameters to be transmitted. Due to the triggering of the custom event, the callback function can be called to receive data.
12.1.1 method of binding custom events
The first method: bind through v-on(@)
<template> //Bind the hello event on the school component. If the hello event is triggered, call the showinfo function, and the callback remains on the APP component <school @hello = "showinfo"></school> //<school @hello.once = "showinfo"></school> </template> <script> export default { name:"APP", methods:{ showinfo(){ console.log("The function is called") } } } </script>
The second method: label with ref, and bind with $on()
<template> // It needs to be mounted in the form of labeling <school ref = "hello"></school> </template> <script> export default { name:"APP", methods:{ showinfo(){ console.log("The function is called") } }, mounted(){//mount /* The following line of code means: because we bind ref to the component, we return the instantiated object of the component, It is equivalent to binding an event called Demo to vc. If Demo is triggered, shiowinfo function will be called */ this.$refs.hello.$on("Demo",this.showinfo) // If you want to execute it once, you can use the $once modifier // this.$refs.hello.$once("Demo",this.Demo) } } </script>
Trigger custom event
this.$emit('custom event name ', parameter...)
Unbind custom event
this.$off('custom event name ') can only unbind one event
this.$off()
12.1.2 comparing props and custom components
The following two examples are examples of data transfer from child components to parent components
props mode
school component (sub component)
<template> <div> <h3>name:{{name}}</h3> <h3>address:{{address}}</h3> <button @click="showinfo">Click to output basic information</button> </div> </template> <script> export default { name:"School", data(){ return{ name:"Jack", address:"China" } }, methods:{ showinfo(){ //Use function this.info(this.name,this.address) } }, //Receive functions from App props:["info"] } </script>
APP component (parent component)
<template> <!-- towards school Pass a component info function --> <school :info = "info"></school> </template> <script> import School from "./components/School.vue" export default { name:"App", components:{School}, methods:{ info(name,address){ console.log(name+"--"+address); } } } </script>
How to customize components
school component (sub component)
<template> <div> <h3>name:{{name}}</h3> <h3>address:{{address}}</h3> <button @click="showme">Click to output basic information</button> </div> </template> <script> export default { name:"School", data(){ return{ name:"Jack", address:"China" } }, methods:{ showme(){ // Trigger info event and pass in parameters this.$emit("info",this.name,this.address) } } } </script>
APP component (parent component)
<template> <!-- to school Component binding info Event, when info Called when the event is triggered showinfo function --> <school @info="showinfo"></school> </template> <script> import School from "./components/School.vue" export default { name:"App", components:{School}, methods:{ showinfo(name,address){ console.log(name+"--"+address); } } } </script>
12.1.3 component customization event summary
- The above two methods are only applicable to the communication between child components and parent components
- This method is not suitable for communication between intergenerational components or sibling components
- If you want a custom event to be triggered only once, you can use the once modifier or the $once method
- Unbind the custom event this$ Off ('custom event name ')
- You can also bind native DOM events on components, and you need to use the native modifier.
- Note: through this$ refs. xxx.$ On ('custom event name ', callback) when Binding custom events, the callback is either configured in methods or used as an arrow function, otherwise there will be problems with this pointing!
12.2 global event bus (very important)
12.2.1 principles and concepts
Principle: use = = component to customize event = = cooperate with built-in relationship
Function: realize the communication between any components
Install global event bus
new Vue({ beforeCreate(){ /* Install global event bus $bus = this = vm Why can the following code complete the global event bus? Because it meets two conditions: 1.All components can see an important built-in relationship mentioned earlier vueComponent.prototype._proto_ === Vue.prototype 2.It satisfies the related API s of $on,$emit,$off */ Vue.prototype.$bus = this } })
12.2 using global bus events
Summary:
-
Whoever wants to receive data will bind custom events to $bus under which component, and the event callback is also in the component
-
The component that provides data triggers a custom event in $bus
test component
<template> <div> <h3>hello everyone! I am{{name}}</h3> <h3>I come from{{address}}</h3> <button @click="show">Point me</button> </div> </template> <script> export default { data(){ return{ name:"Jack", address:"China" } }, methods:{ show(){ this.$bus.$emit("Demo",this.name,this.address) } } } </script> <style> </style>
school component
<template> <div> <h3>I am school assembly</h3> </div> </template> <script> export default { name:"school", methods:{ showinfo(name,address){ console.log(name+"-"+address); } }, mounted(){ this.$bus.$on("Demo",this.showinfo) } } </script> <style> </style>
12.2.3 unbinding
It's best to form a good habit. In the beforeDestroy hook, use $off to unbind the events used by the current component
export default { name:"school", methods:{ showinfo(name,address){ console.log(name+"-"+address); } }, mounted(){ this.$bus.$on("Demo",this.showinfo) }, beforeDestroy(){ this.$bus.$off("Demo") } }
12.3 message subscription and publication
12.3.1 preparation
The PubSubJS library is used here
Steps to use:
-
Install pubsub: NPM I pubsub JS
-
Import: import PubSub from 'PubSub JS'
-
Receive data: if component a wants to receive data, it subscribes to messages in component A, and the subscribed callback remains in component a itself. (in fact, the idea is the same as that of the global event bus)
-
Subscription message (receiving data): PubSub Subscribe ('xxx ', function (XXX, data) {})
-
Publish message (provide data): PubSub Publish ('xxx ', data)
-
It is best to use PubSub. In the beforeDestroy hook Unsubscribe (PID) to unsubscribe.
Note that if you want to cancel the subscription, you need to obtain the id of the subscription before you can cancel it
const pid = PubSub.subscribe('xxx', function(xxx, data) {}) the result it returns is the subscription id
12.3.2 subscribe to and publish messages
Subscribe to messages
PubSub.subscribe('msg', function(msgName, data){}) msg: Indicates the event name msgName: Also represents the event name data: Indicates the data received
Release news
PubSub.publish('msg', data) msg: Indicates the event name data: Represents the data to be passed in
12.3.3 cases
school component
<template> <div class="school"> <h2>School Name:{{name}}</h2> <h2>School address:{{address}}</h2> </div> </template> <script> //Import pubsub import pubsub from 'pubsub-js' export default { name:'School', data() { return { name:'Tsinghua University', address:'Beijing', } }, mounted() { this.pubId = pubsub.subscribe('hello',(msgName,data)=>{ console.log(this) //Because the arrow function this is written to point to vc console.log('Someone posted it hello News, hello The callback of the message was executed',msgName,data) }) }, beforeDestroy() { pubsub.unsubscribe(this.pubId) }, } </script> <style scoped> .school{ background-color: skyblue; padding: 5px; } </style>
student component
<template> <div class="student"> <h2>Student Name:{{name}}</h2> <h2>Student gender:{{sex}}</h2> <button @click="sendStudentName">Give the students their names School assembly</button> </div> </template> <script> import pubsub from 'pubsub-js' export default { name:'Student', data() { return { name:'Zhang San', sex:'male', } }, mounted() { // console.log('Student',this.x) }, methods: { sendStudentName(){ pubsub.publish('hello',this.name) } }, } </script> <style lang="less" scoped> .student{ background-color: pink; padding: 5px; margin-top: 30px; } </style>
summary
The above is what I want to talk about today. This paper introduces the communication between components (custom event, global event bus, message subscription and Publication). I hope it will be helpful to you!