[Vue] Part XII communication between components (custom event, global event bus, message subscription and Publication) is very important

[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

  1. Function: it can realize the communication between child components = = > parent components

  2. 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

  1. The above two methods are only applicable to the communication between child components and parent components
  2. This method is not suitable for communication between intergenerational components or sibling components
  3. If you want a custom event to be triggered only once, you can use the once modifier or the $once method
  4. Unbind the custom event this$ Off ('custom event name ')
  5. You can also bind native DOM events on components, and you need to use the native modifier.
  6. 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:

  1. Install pubsub: NPM I pubsub JS

  2. Import: import PubSub from 'PubSub JS'

  3. 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)

  4. Subscription message (receiving data): PubSub Subscribe ('xxx ', function (XXX, data) {})

  5. Publish message (provide data): PubSub Publish ('xxx ', data)

  6. 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!

Keywords: Javascript Front-end Vue.js

Added by worldofcarp on Sat, 26 Feb 2022 19:06:19 +0200