In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)05/31 Report--
This article mainly explains "what are the ways to achieve communication between components in Vue". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "what are the ways to achieve communication between components in Vue?"
1. Which scenarios require communication?
Because all the components of Vue are in the form of a component tree, there are many situations in which components communicate with each other, roughly as follows:
Communication between parent and child components
Communication between sibling components
Communication between intergenerational components
No communication between related components
The communication method recommended in each scenario is also different, and the most appropriate communication mode between components needs to be selected according to different scenarios.
2.props and $emit
This method is usually used for passing values between parent and child components, where the parent component passes the value to the child component through attributes, and the child component receives it through props. The child component passes data to the parent component through events.
Initialize the project:
We set up the simplest Vue project with three components: parent, child1 and child2, and then introduce the parent component into the APP.vue and the child1 and child2 subcomponents into the parent component. The initial running interface is as follows:
2.1 parent components pass values to child components
Next, we use properties to pass values from the parent component to the child component.
Sample code for parent components:
/ / src/views/parent.vue
Parent component
Change the data import child1 from ". / child1.vue"; import child2 from ". / child2.vue"; export default {data () {return {msg: "I am the data of the parent component",};}, components: {child1, child2,}, methods: {/ / Click the button to change the data changeMsg () {this.msg = "turn into a piggy classroom" },},}
We pass the msg in the parent component to the child component through: msg= "msg", and the msg in the parent component is modified when the button is clicked.
Sample code for subcomponents:
/ / src/views/child1.vue
Child1 component
Parent component data: {{msg}}
Export default {props: {msg: {type: String, default: ",}
The child component receives the data from the parent component through the props property.
Output result:
When we click the button, the data of the parent component changes, and so does the data received by the child component.
Note: the msg received by msg= "msg" is a variable. You can refer to the principle of bind. If you don't add:, you will receive a string.
2.2 the child component passes values to the parent component
The child component can pass a value to the parent component in the form of a $emit custom event, which the parent component needs to listen to to receive the value from the child component.
Sample code for parent components:
/ / src/views/parent.vue
Parent component
Change data subcomponent data: {{childData}} import child1 from ". / child1.vue"; import child2 from ". / child2.vue"; export default {data () {return {msg: "I am the data of the parent component", childData: "",} " }, components: {child1, child2,}, methods: {changeMsg () {this.msg = "become a piggy classroom";}, / listen for subcomponent event childData (data) {this.childData = data;},},}
Sample code for subcomponents:
/ / src/views/child1.vue
Child1 component
Pass data to the parent component
Parent component data: {{msg}}
Export default {props: {msg: {type: String, default: ",},}, methods: {/ / Click the button to pass data to the parent component using $emit () {this.$emit (" childData "," I am the child component data ");},},}
Output result:
We listen for the childData event in the parent component through @ childData= "getChildData" to get the data passed by the child component, and the child component passes the data to the parent component by clicking the button to trigger the $emit event. When we click the button "pass data to the parent component", the parent component can get the data.
3.$parent gets the parent component value
In this way, it is very convenient for the child component to obtain the value of the parent component, not only the data, but also the method.
Sample code for subcomponents:
/ / src/views/child1.vue
Child1 component
Pass data to the parent component using $parent
Parent component data: {{msg}}
Export default {props: {msg: {type: String, default: "",},}, methods: {sendData () {this.$emit ("childData", "I am the child component data");}, / / get the parent component value getParentData () {console.log ("parent component", this.$parent);},},} through $parent
When you click the "use parent" button, when you go through the parent button, when you go through the parent button, you get the properties or data of the parent component through parent.
Output result:
We can see that the console prints out all the properties of the parent component, including not only the data data, but also some of the methods defined in it.
4.$children and $refs get child component values
These two methods are very similar to $parent in that they can directly obtain the relevant properties or methods of the subcomponent, not limited to the data.
Sample code for parent components:
/ / src/views/parent.vue
Parent component
Change data using $children and $refs subcomponent data: {{childData}} import child1 from ". / child1.vue"; import child2 from ". / child2.vue"; export default {data () {return {msg: "I am the data of the parent component", childData: "",} " }, components: {child1, child2,}, methods: {changeMsg () {this.msg = "become a piggy classroom";}, / / listen for the custom event getChildData (data) {this.childData = data;} of the subcomponent, / / use $chilren and $refs to get the subcomponent getChildByRef () {console.log ("use $children", this.$children) Console.log ("use $refs", this.$refs.child1);},},}
Output result:
In the previous code, we click the button to get the sub-components through children and refs respectively, thus getting the sub-component data. It should be noted that children returns all sub-component arrays contained in the current component, children returns all sub-component arrays contained in the current component, and children returns all sub-component arrays contained in the current component. When using refs, you need to add the ref attribute to the sub-component, which is similar to getting the DOM node directly.
5. Use $attrs and $listeners
Attrs is proposed after Vue2.4.0 and is usually used when multi-tier components pass data. If many partners encounter the scenario of multi-tier component data transfer, they may directly choose Vuex for transmission, but if the data we need to pass does not involve data updates and modifications, it is recommended to use $arrts. After all, Vuex is still heavy.
The official website explains:
Contains attribute bindings in the parent scope that are not recognized (and obtained) as prop (except class and style). When a component does not declare any prop, it contains bindings for all parent scopes (except class and style), and internal components can be passed in via vClure bind = "$attrs"-- useful when creating high-level components.
The explanation on the official website is still difficult to understand, and we can explain it again in more common terms.
Popular explanation:
When the parent component passes a lot of data to the child component, the child component does not declare props for receiving, then the attrs attribute in the child component contains all the data from the parent component (except for those already declared by props), and the child component can also use the v − bind= "attrs attribute to contain all the data from the parent component (except for those already declared by props). The attrs attribute contains all the data from the parent component (except for those already declared by props), and the child component can also pass data to its child component (grandchild component) in the form of v − bind= "attrs". The grandchild component uses $attrs in a similar way to its parent component.
No matter how much you say, there may still be no code that is easy to understand. Let's create a new grandchild component, child1-child.vue, and write it with the following interface:
5.1Use of $attrs
We pass a little more data to the child1 component in the parent parent component.
Sample code for parent components:
/ / src/views/parent.vue
Parent component
Import child1 from ". / child1.vue"; import child2 from ". / child2.vue"; export default {data () {return {msg: "I am the data of the parent component", msg1: "parent data 1", msg2: "parent data 2", msg3: "parent data 3", msg4: "parent data 4", childData: "",} " }, components: {child1, child2,}}
Here we have deleted some code that is not used in this section, and you need to pay attention to it.
Sample code for child1 components:
/ / src/views/child1.vue
Child1 component
Import Child1Child from ". / child1-child"; export default {components: {Child1Child,}, props: {msg: {type: String, default: ",},}, mounted () {console.log (" child1 component gets $attrs ", this.$attrs);}}
Output result:
In the previous code, our parent parent component passed five data to the child components: msg, msg1, msg2, msg3, and msg4. But in the props attribute in the subcomponent, we only receive msg. Then we printed $attrs in the subcomponent mounted and found that there was exactly less msg data received by props.
When we use attrs to receive the component in the child1 component, we can use v − bind= "attrs to receive the component, and we can use v − bind=" attrs "form to pass it to its child component child1-child after receiving the component. We have added v-bind in the previous code.
Sample code for child1-child components:
/ / src/views/child1-child.vue
I am the grandson component child1-child
Export default {props: {msg1: {type: String, default: ",},}, mounted () {console.log (" child1-child component $attrs ", this.$attrs);},}
Output result:
We find that msg1 is missing from the $attrs printed in the child1-child component because we have already received msg1 in props.
5.2. use of $listeners
The listeners property and the attrs property and type, except that they pass something different.
The explanation on the official website:
Contains v-on event listeners in the parent scope (without the. Native modifier). It can pass in internal components via vMuon = "$listeners"-- useful when creating higher-level components.
A popular explanation:
When the parent component defines some custom non-native events on the child component, these custom events can be obtained inside the child component through the $listeners attribute.
The difference between it and attrs is obvious, the difference between attrs is obvious, and the difference between attrs is obvious. Attrs is used to pass properties, and $listeners is used to pass non-native events. Let's print it in the child1 component.
Sample code for child1 components:
/ / src/views/child1.vuemounted () {console.log ("child1 component gets $attrs", this.$attrs); console.log ("child1 component gets $listeners", this.$listeners);}
Output result:
You can see that the childData method is output, which is the listening event that we customized in its parent component. Except for the second time, $listeners can be passed to the underlying component again in the form of v-on.
Sample code for child1 components:
/ / src/views/child1.vue
Child1 component
Pass data to the parent component using $parent
Parent component data: {{msg}}
Sample code for child1-child components:
/ / src/views/child1-child.vuemounted () {console.log ("child1-child component $attrs", this.$attrs); console.log ("child1-child component $listerners", this.$listeners);}
Output result:
You can see that the childData custom event in the parent parent component is also obtained in the child1-child grandchild component. The advantage of using listeners is that if there are multi-level components, the advantage of not using listeners is that if there are multi-level components, there is no need to use listeners: if there are multi-level components, there is no need to use emit to trigger events up step by step, you only need to use $listerners to get custom events in the parent component, which is equivalent to being lazy.
5.3 inheritAttrs
Perhaps careful friends will find that when we use $attrs, the attributes we passed are rendered together on the DOM node rendered by the child1 sub-component, as shown in the following figure:
This is not what we want, and to solve this problem, we can set the inheritAttrs property in the subcomponent.
The official website explains:
By default, parent-scoped attribute bindings (attribute bindings) that are not considered props will be "fallback" and applied to the root element of the child component as a normal HTML attribute. When writing a component that wraps a target element or another component, this may not always behave as expected. By setting inheritAttrs to false, these default behaviors will be removed. These attribute can be made effective through the instance property $attrs, which is also added in 2.4. and can be explicitly bound to non-root elements through v-bind.
The official website said a lot, but it is not very popular, we can understand it simply.
Popular explanation:
The parent component passes a lot of data to the child component, and the props of the child component is not fully received, so the data passed by the parent component will be rendered to the HTML. We can set the inheritAttrs to false for the child component to avoid this rendering.
Sample code for child1 components:
/ / src/views/child1.vueprops: {msg: {type: String, default: ",},}, inheritAttrs: false
Output result:
At this point, there are no extraneous node attributes on our node.
5.4 Summary
$attrs: used to pass properties, such as class, style, and so on, it is an object.
$listeners: used to pass an event, a native event, which is also an object.
Attrs and listeners can solve the problem of data and event transfer between multi-tier components.
InheritAttrs resolves attribute rendering of data received without using props.
6. Custom events: event bus
When we are working on a project, we will find that it is troublesome to transfer data between unrelated components, such as sibling components and cross-level components. Without using Vuex, we can use custom events (also known as event centers) to achieve data transfer.
The idea of the event center is also relatively simple: the middle center has two main functions: triggering events and listening for events. If the data needs to be transferred between the two components, component A can trigger the event of the event center, and component B listens to the event of the event center, so that there is an association between the two components to achieve data transfer.
Implementation steps:
To simplify the demonstration, let's register an event center globally and modify the main.js.
The main.js code is as follows:
/ / src/main.jsVue.config.productionTip = falseVue.prototype.$EventBus = new Vue () new Vue ({router, store, render: h = > h (App)}). $mount ('# app')
Sample code for child1 components:
Child1 component
Send data import Child1Child from ". / child1-child" to child2 component; export default {methods: {/ / send data to child2 component via event bus toChild2 () {this.$EventBus.$emit ("sendMsg", "I am the data from child1 component");},},}
Call EventBus.EventBus.EventBus.emit in the child1 component to add a sendMsg event to the event center, which is somewhat similar to the relationship with props and $emit.
Sample code for child2 component 2:
/ / src/views/child1.vue
Child2 component
Parent component data: {{msg}}
Export default {props: {msg: {type: String, default: ",},}, mounted () {this.$EventBus.$on (" sendMsg ", (msg) = > {console.log (" data received from child1 ", msg);});},}
When we click the button in the child1 component, the sendMsg event is triggered, and in the child2 component we listen for the event, so we receive data from the child1 component.
Output result:
The way the event center implements data transmission is actually the pattern of a publisher and subscriber, which can achieve communication between any component.
7.provide and inject
These two are added in Vue2.2.0 API,provide and inject need to be used together. They can also implement data communication between components, but you need to ensure that the components are parent-child relationships.
The explanation on the official website:
This 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 level, and remain in effect for the time when its upstream and downstream relationship is established.
The explanation on the official website is very clear, so here we do not need a popular explanation, a simple sentence: the parent component can inject dependency into the child component (regardless of hierarchy), and each child component can obtain this dependency, regardless of level.
Parent sample code:
/ / src/views/parent.vueimport child1 from ". / child1.vue"; import child2 from ". / child2.vue"; export default {provide () {return {parentData: this.msg} }, data () {return {msg: "I am the data of the parent component", msg1: "parent data 1", msg2: "parent data 2", msg3: "parent data 3", msg4: "parent data 4", childData: "",};}, components: {child1, child2,},}
Sample code for child1-child components:
/ / src/views/child1-child.vue
I am the grandson component child1-child
Parent component data: {{parentData}}
Export default {inject: ["parentData"], props: {msg1: {type: String, default: "",},}, mounted () {console.log ("child1-child component $attrs", this.$attrs); console.log ("child1-child component $listerners", this.$listeners); console.log ("child1-child component obtains parent component data", this.parentData)},}
Output result:
Through the combination of provide and inject, we get the data in the parent component in the child1-child component. If you try it down, you may find that the data is not responsive, that is, the parent component has changed the data, and the data in the child1-child component will not be updated.
To become responsive, we need to modify the way provide is delivered.
The parent code is as follows:
/ / src/views/parent.vueimport child1 from ". / child1.vue"; import child2 from ". / child2.vue"; export default {provide () {return {parentData: this.getMsg} }, data () {return {msg: "I am the data of the parent component", msg1: "parent data 1", msg2: "parent data 2", msg3: "parent data 3", msg4: "parent data 4", childData: "",} }, components: {child1, child2,}, methods: {/ / return data data getMsg () {return this.msg;},},}
At this point we will find that the data becomes responsive.
The principles of porvide and inject can be seen in the following figure:
8.Vuex and localStorage
These two methods should be the most frequently used by partners in actual projects, so here not only to elaborate, but only to mention the difference between the two.
Vuex:
Vuex is the state manager, the data it stores is not persistent, and once the page is refreshed or the project data is closed, the data is gone.
The data stored by Vuex is responsive.
Localstorage:
LoacalStorage is a way of data storage in HTML5, persistent storage, the stored data is not responsive.
9.v-model
V-model is a built-in instruction in vue, which is usually used on form elements to achieve two-way data binding. Its essence is the syntax sugar of v-on and v-bind. Here we can also use it to achieve data transmission in some scenarios. Note that the scene here must be a parent-child component.
Sample code for parent components:
Parent component
ModelData: {{modelData}} import child2 from ". / child2.vue"; export default {provide () {return {parentData: this.getMsg};}, data () {return {modelData: "model data of parent components"};}, components: {child1,},}
Sample code for child2 components:
Child2 component
Modify v-model data export default {props: {value: {type: String, default: "",},}, mounted () {console.log ("child2 component receives attachments see data passed by v-model", this.value) }, methods: {/ / trigger the input event of the parent component through $emit and pass the second parameter to the parent component confirm () {this.$emit ("input", "modify the v-model data passed by parent");},},}
We use v-model in the parent component to pass data to the child 2 child component, use the default value attribute to receive it in the child component's props, and use $emit to trigger the default input event in the parent component in the child component. At this time, the data passed will change between the child component and the parent component, which is called bidirectional data binding.
Thank you for your reading, the above is the content of "what are the ways to achieve communication between components in Vue". After the study of this article, I believe you have a deeper understanding of the way to achieve communication between components in Vue, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
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.