This article mainly introduces the event dispatching mechanism between Vue2.0 parent and child components. Now I will share it with you and give you a reference.
Everyone who has come from vue1.x knows that in vue2.0, $dispatch and $broadcase for event communication between parent and child components have been removed. The official consideration is that the event flow method based on the component tree structure is really difficult to understand, and will become more and more brittle as the component structure expands. Especially when the component hierarchy is relatively deep. Through the mechanism of broadcasting and event distribution, it seems more confusing.
While abolishing it, the official also provided us with a replacement plan, including instantiating an empty vue instance and using $emit to react to state changes on the subcomponent
1. Use $emit to trigger the event
helloWorld.vue as the parent component, and the dialogConfigVisible variable controls the display or hiding of the sub-component pop-up box.
configBox.vue is used as a subcomponent, assuming it is an encapsulated announcement pop-up window.
In helloWorld.vue in the parent component
<config-box :visible="dialogConfigVisible" @listenToConfig="changeConfigVisible" > </config-box>
script
data(){ return { dialogConfigVisible:true } } methods: { changeConfigVisible(flag) { this.dialogConfigVisible = flag; } }
Then, in the child component configBox.vue , mainly in any event callback, use $emit to trigger the custom listenToConfig event, and then you can add parameters and pass them to the parent component. For example, when you click × on the child component pop-up window to close, the parent component helloWorld.vue is notified that I want to close it. This is mainly to facilitate the parent component to change the corresponding state variables and pass false to the custom event.
script
methods:{ dialogClose() { this.show = false; this.$emit("listenToConfig", false) } }
In the child component, actively trigger the listenToConfig event and pass in the parameter false to tell the parent component that the helloWorld.vue dialog box is about to close. Here you can avoid that the state in the parent component has not changed, and the dialog box will automatically appear when the page is refreshed again.
2. Instantiate an empty vue instance bus
A bus empty vue instance is instantiated here, mainly to uniformly manage the communication between sub-components and parent components, through bus as a medium, first create a bus.js file, create a new object in it, the parent component is table.vue, the child 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 them respectively:
// table.vue <script> import {bus} from "./bus" export default { created(){ bus.$on('getData',(argsData)=>{ // 这里获取子组件传来的参数 console.log(argsData); }) } } </script>
// tableColumn.vue <script> import {bus} from "./bus" export default{ methods(){ handleClick(){ bus.$emit('getData',{data:"from tableColumn!"}) } } } </script>
above In the parent-child component, the parent component uses bus to register the listening event getData. Once there is a state change in the child component, the corresponding event on the bus is triggered.
This method of using empty instances is equivalent to creating an event center, so this kind of communication is also suitable for communication between non-parent-child components.
3. Multi-level parent-child Component communication
Sometimes, the two components that may want to communicate are not direct parent-child components, but grandfather and grandson, or parent-child components that span more levels
It is impossible for sub-components to pass parameters upward level by level to achieve the purpose of communication, although the communication we understand now is relayed in this way. You can continue to traverse upward through while loops until you find the target parent component, and then trigger the event on the corresponding component.
The following is a mixins for parent-child component communication implemented by element-ui, which plays a great role in component synchronization. This component communication is also specifically mentioned in the overview of the advantages of element-ui
function broadcast(componentName, eventName, params) { // 向下遍历每个子节点,触发相应的向下广播的 事件 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: { // 向上遍历父节点,来获取指定父节点,通过$emit 在相应的 组件中触发 eventName 事件 dispatch(componentName, eventName, params) { var parent = this.$parent || this.$root; var name = parent.$options.componentName; // 上面的componentName 需要在每个vue 实例中额外配置自定义属性 componentName, //可以简单替换成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 example is:
<f1> <c1></c1> </f1>
Then, Define two parent and child components respectively:
c2.vue
<template> <section> <button type="button" name="button" @click="dispatchTest">点击一下,就可以</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"> <p class="outBox-class"> <slot> </slot> </p> </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. This event is monitored in the component, and
is actually more similar to the $emit trigger event. The difference is that it can be nested at multiple levels, not necessarily direct parent-child components can be triggered.
The above is what I compiled for everyone. I hope it will be helpful to everyone in the future.
Related articles:
How to format the current time through js?
Using vue to introduce css, less related issues
How to introduce public css files through vue
What are the methods for using ajax in Vue?
The above is the detailed content of Regarding the implementation of dispatch mechanism between Vue2.0 parent and child components (detailed tutorial). For more information, please follow other related articles on the PHP Chinese website!