In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
How to deeply understand the seven communication modes of Vue components, I believe that many inexperienced people are at a loss about this. Therefore, this paper summarizes the causes and solutions of the problems. Through this article, I hope you can solve this problem.
The way vue components communicate is a very frequent question in the interview. I often encountered this problem when I first started looking for an internship. At that time, I only knew how to go back to props and $emit. Later, with the deepening of study, I found that there are so many ways to communicate with vue components!
Today, the communication mode of vue components is summarized. If there are omissions in the writing, please leave a message.
1. Brief introduction to props/$emit
Props and $emit are familiar to all of you, and this is our most commonly used vue communication method.
The props:props can be an array or object that receives data from the parent component passing through the v-bind. When props is an array, it directly receives the properties passed by the parent component; when props is an object, you can set the type, default value, required and verification rules of the properties through type, default, required, validator and other configurations.
$emit: when the parent and child components communicate, we usually use $emit to trigger the parent component v-on to bind the corresponding event listening on the child component.
Code example
Let's use the code to implement the communication between the parent and child components of props and $emit, and in this example, we all implement the following communication:
Parent-to-child value: the parent component passes the parent component message value to the child component through: messageFromParent= "message". When the parent component's input tag is entered, the content in the child component p tag changes accordingly.
The child passes the value to the parent: the parent component binds the listening for receive events on the child component through @ on-receive= "receive". When the child component input tag is input, it will trigger the receive callback function, assign the value of the child component message to the parent component messageFromChild through this.$emit ('on-receive', this.message), and change the content of the parent component p tag.
Please look at the code:
/ / Sub-component code this is child component
Received a message from the parent component: {{messageFromParent}}
Export default {name: 'Child', props: [' messageFromParent'], / / receives the message data () {return {message:',} from the parent component through props, methods: {send () {this.$emit ('on-receive', this.message) / / triggers the on-receive event through $emit, calling receive callback in the parent component And take this.message as the parameter},},} / / parent component code this is parent component
Received a message from the subcomponent: {{messageFromChild}}
Import Child from'. / child'export default {name: 'Parent', data () {return {message:', / / message passed to the subcomponent messageFromChild:',}}, components: {Child,}, methods: {receive (msg) {/ / accept the information of the subcomponent and assign it to messageFromChild this.messageFromChild = msg},},}
Effect preview
2. Introduction to v-slot
V-slot is a new api for unified implementation of slots and named slots in the Vue2.6 version, which is used to replace api such as slot (2.6.0 obsolete), slot-scope (2.6.0 obsolete) and scope (2.5.0 obsolete).
V-slot is used in the template tag to provide named slots or slots that need to receive prop. If v-slot is not specified, the default value is default.
Code example
Let's take a look at the code example of v-slot, where we implemented:
Parent-to-child value: the parent component passes the message value of the parent component to the child component through {{message}}, and the child component passes the value from the parent to the child by receiving the corresponding content.
/ / Sub-component code this is child component
Received a message from the parent component:
This is parent component {{message}} import Child from'. / child'export default {name: 'Parent', data () {return {message:',}}, components: {Child,},}
Effect preview
3. Introduction to $refs/ $parent/ $children/$root
We can also get the Vue component instance through $refs/$parent/$children/$root and get the properties and methods bound on the instance to realize the communication between components.
$refs: we usually bind $refs to the DOM element to get the attributes of the DOM element. In implementing component communication, we can also bind $refs to a subcomponent to get the subcomponent instance.
Parent: we can get the parent component instance of the current component, if any, directly through this.$parent in Vue.
$children: similarly, we can also get an array of child component instances of the current component directly through this.$children in Vue. It is important to note, however, that the subscript of elements in the this.$children array does not necessarily affect the order of child components referenced by the parent component, such as those that are loaded asynchronously, which may affect their order in the children array. So when using, you need to find the corresponding sub-components according to certain conditions, such as the name of the sub-components.
$root: gets the root Vue instance of the current component tree. If the current instance does not have a parent instance, the instance will be itself. With $root, we can achieve cross-level communication between components.
Code example
Let's take a look at an example of the use of $parent and $children (since these api are used in more or less the same way, the use of $refs and $root is not expanded here, but is implemented in this example:
Parent-to-child value: the child component gets the value of message in the parent component through $parent.message.
The child passes the value to the parent: the parent component obtains the array of the child component instance through $children, traverses the array, obtains the corresponding Child1 child component instance through the name of the instance, assigns it to the child1, and then obtains the message of the Child1 child component through child1.message.
The code is as follows:
/ / Sub-component this is child component
Received a message from the parent component: {{$parent.message}}
Export default {name: 'Child1', data () {return {message:', / / parent component can obtain message}},} / / parent component this is parent component of child component instance through this.$children
Received a message from the subcomponent: {{child1.message}}
Import Child from'. / child'export default {name: 'Parent', data () {return {message:', child1: {},}}, components: {Child,}, mounted () {this.child1 = this.$children.find ((child) = > {return child.$options.name = 'Child1' / / obtain the child instance of the corresponding name via options.name})},}
Effect preview
4. Brief introduction to $attrs/$listener
Both $attrs and $listeners are new attributes in Vue2.4 and are mainly used by users to develop advanced components.
Attrs: used to receive attribute attributes in the parent scope that are not recognized as prop, and can be passed into internal components via vMutual = "$attrs"-useful when creating high-level components.
Imagine that when you create a component, you receive param1, param2, param3... If you pass props, you need to pass props: ['param1',' param2', 'param3',...] Waiting for a lot of announcements. It will be even more troublesome if some of these props need to be passed on to deeper subcomponents.
With $attrs, you don't need any declaration, directly through $attrs.param1, $attrs.param2... It can be used, and it is very convenient to pass the example above to the deep subcomponents.
Listeners: contains the v-on event listeners in the parent scope. It can pass in internal components via vMuon = "$listeners"-- useful when creating higher-level components, which is very similar to $attrs when passing.
Code example
In this example, there are three components: a, B, and C, with the relationship [A [B [C]]], where An is the parent of B and B is the parent of C. That is, level 1 component A, level 2, component B, level 3, component C. We have achieved:
Parent-to-child value: level 1 component A passes the message attribute to level 2 component B by: messageFromA= "message". Level B gets the message of level 1 component A through $attrs.messageFromA.
: messageFromA= "message" v talk binding = "$attrs" $attrs.messageFromA
Child-to-parent value: level 1 component A binds the listening of keyup events on descendant components through @ keyup= "receive", and level 2 component B binds keyup events to its input tag through vMuon = "$listeners". When the level 2 component B input input box is entered, the receive callback of level 1 component A will be triggered, and the value in the input input box of level 2 component B will be assigned to the messageFromComp of level 1 component A, so that the child can pass the value to the parent.
@ keyup= "receive" v talk = "$listeners"
The code is as follows:
/ / level 3 component C this is C component
Received a message from component A: {{$attrs.messageFromA}}
Export default {name: 'Compc', data () {return {message:',}},} / / level 2 component B this is B component
Received a message from component A: {{$attrs.messageFromA}}
Import CompC from'. / compC'export default {name: 'CompB', components: {CompC,}, data () {return {message:',}},} / A component this is A component
Received a message from {{comp}}: {{messageFromComp}}
Import CompB from'. / compB'export default {name: 'CompA', data () {return {message:', messageFromComp:', comp:',}}, components: {CompB,}, methods: {receive (e) {/ / listens to the callback of the descendant component keyup event And assign the value of the input input box where keyup is located to messageFromComp this.comp = e.target.name this.messageFromComp = e.target.value},},}
Effect preview
5. Introduction to provide/inject
The provide/inject pair of options need to be used together to allow an ancestral component to inject a dependency into all its descendants, no matter how deep the component hierarchy, and remain in effect for the duration of its upstream and downstream relationships. If you are a student who is familiar with React, you will immediately think of the api of Context. The two are very similar.
Provide: is an object, or a function that returns an object. This object contains the property that can be injected into its descendants, that is, the attributes and property values to be passed to the descendants.
Injcet: an array of strings, or an object. When it is a string array, it is used in a very similar way to props, except that the properties received are changed from data to properties in provide. When it is an object, it is also similar to props, you can set default values by configuring properties such as default and from, and use new named properties in sub-components, and so on.
Code example
In this example, there are three components, level 1 component A, level 2 component B, level 3 component C: [a [B [C]]], An is the parent component of B, and B is the parent component of C. It is implemented in the example:
Parent-to-child value: level 1 component An injects message into descendant components through provide, level 2 component B receives message in level 1 component A through inject: ['messageFromA'], and obtains the content attribute value of message in level 1 component A through messageFromA.content.
Cross-level downward transfer value: level 1 component An injects message into descendant components through provide, level 3 component C receives the message in level 1 component A through inject: ['messageFromA'], and obtains the content attribute value of message in level 1 component A through messageFromA.content.
The code is as follows:
/ / level 1 component A this is A component import CompB from'. / compB'export default {name: 'CompA', provide () {return {messageFromA: this.message, / / pass message to descendant components via provide}}, data () {return {message: {content:',},}}, components: {CompB,} } / / level 2 component B this is B component
Received a message from component A: {{messageFromA & & messageFromA.content}}
Import CompC from'. / compC'export default {name: 'CompB', inject: [' messageFromA'], / / accept the message components passed by provide in A via inject: {CompC,},} / / level 3 component C this is C component
Received a message from component A: {{messageFromA & & messageFromA.content}}
Export default {name: 'Compc', inject: [' messageFromA'], / / accept the message passed by provide in A via inject
Note:
Some students may want to ask me why the message in level 1 component An above uses the object type instead of the string type, because the vue provide and inject bindings are not responsive. If message is a string type, it cannot be assigned to messageFromA after changing the message value through the input input box in level 1 component A. if it is an object type, when the object attribute value is changed, the attribute value in messageFromA can be changed accordingly, and the object attribute value received by the descendant component inject can also be changed accordingly.
The descendant provide, which has the same attribute as the ancestor, overrides the ancestor's provision value in the descendant. For example, if the level 2 component B also injects a messageFromA value into the level 3 component C through provide, the messageFromA in the level 3 component C will give priority to receiving the value injected by the level 2 component B over the level 1 component A.
Effect preview
6. Introduction to eventBus
EventBus, also known as event bus, realizes global communication of components by registering a new Vue instance, listening for and triggering events of this instance by calling $emit and $on of this instance, and passing in parameters. It is a component that does not have DOM, only its instance methods, so it is very portable.
We can register on the global Vue instance by:
/ / main.jsVue.prototype.$Bus = new Vue ()
But when the project is too large, it is best to abstract the event bus into a single file and import it into each component file that needs to be used. In this way, it does not pollute the global namespace:
/ / bus.js, the principle analysis of import Vue from 'vue'export const Bus = new Vue () is introduced through import.
In fact, the principle of eventBus is relatively simple, which is to use the subscription-publish model to implement $emit and $on:
/ / eventBus principle export default class Bus {constructor () {this.callbacks = {}} $on (event, fn) {this.callbacks [event] = this.callbacks [event] | | [] this.callbacks [event] .push (fn)} $emit (event) Args) {this.callbacks [event] .forEach ((fn) = > {fn (args)})}} / / introduce the following / / Vue.prototype.$bus = new Bus () code example into main.js
In this example, there are four components: [a [B [C, D], level 1 component A, level 2 component B, level 3 component C and level 3 component D. We achieved this by using eventBus:
Global communication: that is, parent and child components communicate with each other, sibling components communicate with each other, and cross-level components communicate with each other. The operation logic of the four components is the same. In the input input box, the sendMessage event callback is triggered through this.$bus.$emit ('sendMessage', obj), which encapsulates sender and message as parameters; at the same time, the sendMessage events of other components are listened through this.$bus.$on (' sendMessage', obj), and the values of sender and message of the current component examples are given. In this way, when any component input input box value changes, other components can receive the corresponding information and achieve global communication.
The code is as follows:
/ / main.jsVue.prototype.$bus = new Vue () / / level 1 component A this is CompA received a message of {{sender}}: {{messageFromBus}}
Import CompB from'. / compB'export default {name: 'CompA', components: {CompB,}, data () {return {message:', messageFromBus:', sender:',}}, mounted () {this.$bus.$on ('sendMessage') (obj) = > {/ / listen for sendMessage events via eventBus const {sender, message} = obj this.sender = sender this.messageFromBus = message})}, methods: {sendMessage () {this.$bus.$emit ('sendMessage', {/ / sendMessage events triggered by eventBus sender: this.$options.name, message: this.message })},}, / / level 2 component B this is CompB received a message from {{sender}}: {{messageFromBus}}
Import CompC from'. / compC'import CompD from'. / compD'export default {name: 'CompB', components: {CompC, CompD,}, data () {return {message:', messageFromBus:', sender:',}}, mounted () {this.$bus.$on ('sendMessage') (obj) = > {/ / listen for sendMessage events via eventBus const {sender, message} = obj this.sender = sender this.messageFromBus = message})}, methods: {sendMessage () {this.$bus.$emit ('sendMessage', {/ / sendMessage events triggered by eventBus sender: this.$options.name, message: this.message })},}, / / level 3 component C
This is CompC
Received a message from {{sender}}: {{messageFromBus}}
Export default {name: 'CompC', data () {return {message:', messageFromBus:', sender:',}}, mounted () {this.$bus.$on ('sendMessage', (obj) = > {/ / listen for sendMessage events const {sender via eventBus Message} = obj this.sender = sender this.messageFromBus = message})}, methods: {sendMessage () {this.$bus.$emit ('sendMessage', {/ / sendMessage event triggered by eventBus sender: this.$options.name, message: this.message,})},} / / level 3 component D
This is CompD
Received a message from {{sender}}: {{messageFromBus}}
Export default {name: 'CompD', data () {return {message:', messageFromBus:', sender:',}}, mounted () {this.$bus.$on ('sendMessage', (obj) = > {/ / listen for sendMessage events const {sender via eventBus Message} = obj this.sender = sender this.messageFromBus = message})}, methods: {sendMessage () {this.$bus.$emit ('sendMessage', {/ / sendMessage event triggered by eventBus sender: this.$options.name, message: this.message,})},},}
Effect preview
The picture is too large and the screenshot is processed.
7. Vuex
When the project is large, when multiple people maintain the same project, if the event bus is used for global communication, it is easy to make the changes of global variables difficult to predict. Hence the birth of Vuex.
Vuex is a state management model developed specifically for Vue.js applications. It uses centralized storage to manage the state of all components of the application, and uses corresponding rules to ensure that the state changes in a predictable way.
About the content of Vuex, you can refer to the official document of Vuex [1], I will not play tricks here, just look at the code.
Code example
The instance of Vuex and the event bus leisi also contain four components: [a [B [C, D], level 1 component A, level 2 component B, level 3 component C and level 3 component D. We implemented this in this example:
Global communication: the content of the code is similar to that of eventBus, but much easier to use than eventBus. Each component listens for changes in the input input box through watch and triggers mutations through the commit of vuex, thus changing the value of stroe. Then each component dynamically acquires the data in store through computed, thus realizing global communication.
/ store.jsimport Vue from 'vue'import Vuex from' vuex'Vue.use (Vuex) export default new Vuex.Store ({state: {message: {sender:', content:',},}, mutations: {sendMessage (state, obj) {state.message = {sender: obj.sender, content: obj.content,}},},} }) / / component A this is CompA receives a message from {{sender}}: {{messageFromStore}}
Import CompB from'. / compB'export default {name: 'CompA', components: {CompB,}, data () {return {message:',}}, computed: {messageFromStore () {return this.$store.state.message.content}, sender () {return this.$store.state.message.sender},} Watch: {message (newValue) {this.$store.commit ('sendMessage', {sender: this.$options.name, content: newValue,})},},}
Also as in eventBus, the script part of the code in the BPerine Cpene D component is the same except for the difference in importing subcomponents, so it is no longer written up.
Effect preview
Summary
All in all, the component communication methods of 7 Vue are mentioned above, and the types of communication they can carry out are shown in the following figure:
Props/$emit: can achieve two-way communication between parent and child components, which is generally our most commonly used choice in daily parent-child component communication.
V-slot: you can realize one-way communication between parent and child components (passing values from parent to child). When implementing reusable components, passing DOM nodes, html and other contents into components, and the secondary processing of table values of some component libraries, v-slot can be given priority.
$refs/$ parent/ $children/ $root: can be used to achieve two-way communication between parent and child components, where $root enables root component instances to cross-level and one-way pass values to descendant components. When the parent component does not pass a value or listens through the v-on binding, parents and children can consider using these api when they want to get each other's properties or methods.
$attrs/ $listeners: can achieve cross-level two-way communication, allowing you to simply get incoming properties and bound listeners, and easily pass to lower-level subcomponents, which is very useful when building high-level components.
Provide/inject: you can achieve cross-level one-way communication and lightly inject dependencies into descendant components, which is your best choice when implementing advanced components and creating component libraries.
EventBus: can achieve global communication, in the case of a small project, you can use eventBus to achieve global event monitoring. However, eventBus should be used with caution to avoid global contamination and memory leaks.
Vuex: enables global communication and is the best practice for global state management of vue projects. When the project is large and you want to centrally manage the state of global components, then installing Vuex must be right!
After reading the above, have you mastered how to gain an in-depth understanding of the seven ways in which Vue components communicate? If you want to learn more skills or want to know more about it, you are welcome to follow the industry information channel, thank you for reading!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.