Talking about the event dispatching mechanism between Vue2.0 parent and child components, and vue2.0 Dispatching
From vue1.x, we all know that in vue2.0, $ dispatch and $ broadcase for event communication between parent and child components are removed. The official consideration is that the event stream method based on the component tree structure is hard to understand and will become increasingly brittle during the component structure expansion process. Especially when the component level is deep. Through the broadcast and event distribution mechanisms, it seems chaotic.
The official abolition also provides us with a replacement scheme, including instantiating an empty vue instance and using $ emit to reflect the status changes on the child component.
1. Use $ emit to trigger the event
HelloWorld. vue is used as the parent component, and the dialogConfigVisible variable controls the display or hiding of child components in the pop-up box.
ConfigBox. vue is used as a sub-component, which is assumed to be a pop-up window of encapsulated announcements.
In helloWorld. vue of the parent component
<Template/>
<config-box :visible="dialogConfigVisible" @listenToConfig="changeConfigVisible" > </config-box>
Script
data(){ return { dialogConfigVisible:true } } methods: { changeConfigVisible(flag) { this.dialogConfigVisible = flag; } }
Then, in the sub-component configBox. vue, the custom listenToConfig event is triggered by $ emit in any event callback. You can add parameters to the parent component. For example, when you click * close in the Child widget pop-up window, the parent widget helloWorld is notified. I want to disable vue. It is mainly used to enable the parent component to change the corresponding state variable and pass false to the custom event.
Script
methods:{ dialogClose() { this.show = false; this.$emit("listenToConfig", false) }}
In the sub-component, the listenToConfig event is triggered and the parameter false is input to indicate that the helloWorld. vue dialog box of the parent component is closed. This prevents the status of the parent component from changing. The dialog box appears automatically when the page is refreshed again.
2. instantiate an empty vue instance bus
Here, an empty bus vue instance is instantiated. to uniformly manage the communication between child components and parent components, the bus is used as the media to create a new bus. create an object in the js file. The parent component is table. vue. The sub-component is tableColumn. vue
// bus.js import Vue from "vue"; export var bus = new Vue({ data:{ scrollY:false }, methods:{ updateScrollY(flag){ this.scrollY = flag; } } })
Then introduce:
// Table. vue <script> import {bus} from ". /bus "export default {created () {bus. $ on ('getdata', (argsData) =>{// obtain the parameter console from the child component. log (argsData) ;}}}</script>
// tableColumn.vue <script> import {bus} from "./bus" export default{ methods(){ handleClick(){ bus.$emit('getData',{data:"from tableColumn!"}) } } } </script>
In the parent and child components above, the parent component uses the bus to register the listening event getData. Once the Status of the Child component changes, the corresponding event on the bus is triggered.
This method of using an empty instance is equivalent to creating an event center. Therefore, this communication is also applicable to communications between non-Parent and Child components,
3. Multi-level parent-child component communication
Sometimes, the two components that you want to implement communication are not directly parent and child components, but grandfathers and grandchildren, or parent and child components that span more layers.
It is impossible for the sub-component to pass up parameters at the first level to achieve the purpose of communication, although now we understand that communication is like this. You can use a while loop to traverse up until the target parent component is found, and the event is triggered on the corresponding component.
In the following example, only one mixins for parent-child component communication implemented by element-ui plays a significant role in component synchronization. This component communication is also specifically mentioned in the advantages of element-ui.
Function broadcast (componentName, eventName, params) {// traverses each subnode down to trigger the corresponding downward broadcast event this. $ children. forEach (child => {var name = child. $ options. componentName; if (name = componentName) {child. $ emit. apply (child, [eventName]. concat (params);} else {broadcast. apply (child, [componentName, eventName]. concat ([params]) ;}}) ;}export default {methods: {// traverse the parent node up to obtain the specified parent node, use $ emit to trigger eventName in the corresponding component Event dispatch (componentName, eventName, params) {var parent = this. $ parent | this. $ root; var name = parent. $ options. componentName; // The componentName above must be configured with the custom attribute componentName in each vue instance. // you can simply replace it with var name = parent. $ options. _ componentTag; while (parent &&(! Name | name! = ComponentName) {parent = parent. $ parent; if (parent) {name = parent. $ options. componentName ;}}if (parent) {parent. $ emit. apply (parent, [eventName]. concat (params) ;}}, broadcast (componentName, eventName, params) {broadcast. call (this, componentName, eventName, params );}}};
First, define two nested components f1.vue and c1.vue. The instance is:
<f1> <c1></c1> </f1>
Then, two parent and child components are defined:
C2.vue
<Template> <section> <button type = "button" name = "button" @ click = "dispatchTest"> click, you can </button> </section> </template> <script type = "text/javascript"> import Emitter from ".. /mixins/emitter "; export default {name:" c2 ", mixins: [Emitter], componentName: 'c2 ', methods: {dispatchTest () {this. dispatch ('f1 ', 'listenertoc1', false) ;}}</script>
F1.vue
<template type="html"> <div class="outBox-class"> <slot> </slot> </div></template><script type="text/javascript">import Emitter from "../mixins/emitter";export default {name: "f1",mixins: [Emitter],componentName: 'f1',mounted() { this.$on("listenerToC1", (value) => { alert(value); })}}</script>
In this way, you can click the button in the child component to trigger the listenerToC1 event and listen to this event in the parent component,
In fact, the $ emit trigger event is similar. The difference is that multi-level Nesting is allowed here, not all parent and child components can be directly triggered.
The above is all the content of this article. I hope it will be helpful for your learning and support for helping customers.