Vue.js Communication between components

Source: Internet
Author: User
Tags deprecated emit

Lead: The relationship between components is only two, parent-child components and non-parent-child components, this article will describe the communication between the two types of components in detail.

Communication mode between parent and child components 1 (unidirectional binding): Props down, Events up (recommended)

Props down, event up refers to the use of Props to pass data to subcomponents, when the parent component property changes, the child component can update the view in real-time, the subcomponents change, you can use $emit to send the events message to the parent component to pass the change message.

Props is unidirectional, and when the parent component's properties change, it is passed to the child component, but the props property changes in the subassembly do not affect the parent component's property change (except for the Props property type is Object). If you use vue1.0. Sync to force bidirectional, the changes to the child components will affect the state of the parent component, and as the business grows, it is easy to make the data difficult to understand and ultimately into a painful quagmire. As a result, vue2.0 has removed. Sync and is not allowed to change its own props property in subcomponents. If you really need to change the props, that must be a problem with the design, use an alternative, such as: in the data option or the computed option, define a different variable for the conversion. This is props down.

Now that the parent component can pass information through the props, how does the child component's data change notify the parent component?

The appearance of the $emit solves this problem, which is used to send an event message to the parent component, which can be sent with the data information of the child component, and the parent component makes its own corresponding change after receiving the message. Both vue1.0 and vue2.0 support $emit. This is events up.

As shown in example code 1, the parent component passes the data information to the child component through age (props), and the child component gets the latest state through $emit to the parent component. If a subassembly involves a possible change to age, redefine a variable age$ to relay.

"Sample Code 1"

<body><div id= "App" > <p>parent Age: {{age}}</p> <p><button @click = "Changeage" >ch Angeage to 333</button></p> 

  

Communication Mode 2 (bidirectional binding):. Sync or V-model (recommended for use in simple scenes)

In a complex logical component, it is important not to use. Sync, which is easy to halo around N components. , A is the parent component of BC, both AB and AC have a common props attribute (e.g. Model.sync). The model changes in B, in addition to affecting the a,a of the parent component, will also affect component C, at which point C will explode, whether the model changes from a or B. In this way, the model changes become difficult to track and increase maintenance costs. If B or C still watch model, ah, enough to ruin your day's mood.

Parent-child Component direct two-way binding is an implicit drug addict, but for some basic components it is a useful bee that can save a lot of trouble. Some simple-to-base components, or where there is no need to care about data flow. Sync or V-model is the code that looks simple and straightforward.

Sample code 2 and example code 3:

The vue1.0 modifier. Sync can force the props property to two-way binding, such as the sample code 2,checked two-way binding, which makes it easy to complete the radio radio component.

Direct assignment changes to the Prop property in vue2.0 are thrown wrong, but if the Prop property type is object, simply adding or changing properties inside the props property is not a mistake. Because of this attribute, vue2.0 does not support the. Sync modifier.

"Sample Code 2"

<body><div id= "App" >    <radio v-for= "Item in Data": Value= "Item.value": checked.sync= "Checked" >{ {Item.text}} </radio></div><script>    vue.component (' radio ', {        template: ' <label><input type= "Radio": value= "Value" v-model= "Checked" ><slot></slot></label> ",        props: {            value: {},            checked: {}}}    );    New Vue ({        el: ' #app ',        data: {            checked: ',            data: [                {text: ' 2G ', Value: ' 2G '},                {text: ' 3G ', Value: ' 3G '},                {text: ' 4G ', Value: ' 4G '}            ]        }    }) </script></body>

  

Vue2.0 has been deprecated. Sync, but with syntactic sugar V-model, its essence is props down, events up, just because V-model hides the data stream, so call it a two-way binding. The parent component uses the props implicit property value to pass data to the child component, using $emit (' input ') to return the data to the parent component. However, as mentioned above, the use of two-way binding for the underlying component or for components that do not care about data flow is the dregs of the small honey, writing concise, clear.

"Sample Code 3"

<body><div id= "App" >    <radio v-for= "Item in Data": label= "Item.value" v-model= "checked" >{{ item.text}}</radio></div><script>    vue.component (' radio ', {        Template: ' <label> <input type= "Radio": value= "label" v-model= "Checked" ><slot></slot></label> ",        props: {            Label: {},            value: {}        },        computed: {            checked: {                get () {                    return this.value                },                set ( Val) {This                    . $emit (' input ', val)}}}    );    New Vue ({        el: ' #app ',        data: {            checked: ',            data: [                {text: ' 2G ', Value: ' 2G '},                {text: ' 3G ' , value: ' 3G '},                {text: ' 4G ', Value: ' 4G '}            ]        }    ) </script></body>

  

Disassemble the syntax sugar V-model, as shown in example code 4. Well-known friends can skip over.

Code line 4th <child:value= "info" @input = "DataChange" > </child> more <child v-model= "info" ></child> The same effect.

"Sample Code 4"

<body><div id= "App" > <p>parent info: {{info}}</p> <child:value= "info" @input = "DataChange "></child> <p><button @click =" Changeinfo ">changeinfo from parent</button></p>< /div><script> vue.component (' child ', {Template: ' <div><p>child data: {{data}}</p> &L        T;button @click = "Changedata" >changedata from Child</button></div> ', props: {value: {}                }, computed: {data: {get () {return this.value }, set (val) {this. $emit (' input ', Val)}}, M            Ethods: {changedata () {this.data = ' This was a child component! '    }        }    });        New Vue ({el: ' #app ', data: {info: ' This is a original component! ' }, Methods: {DataChange (info{this.info = info}, Changeinfo () {This.info = ' This is a parent            Component! ' }}) </script></body>

  

Communication Mode 3: $broadcast and $dispatch (not recommended)

$dispatch first triggers its own instance, bubbling up until a parent component receives the $dispatch message. If $dispatch is used inside a subassembly, the parent component chain of the component must be cautious when writing a listener event, and the parent component must intercept the message, or it will always bubble. This is a very dangerous behavior, because the components in the parent component chain are difficult to focus on dispatch messages for all subcomponents, and as $dispatch grows in the component, the top-level component or intermediate component wants to know which subassembly the message comes from, which is difficult to trace, and the Abyss of Pain opens.

$broadcast sends a message to each subtree path, and a component of one path receives the message, the path stops sending messages down, as are the other path rules. Similarly $dispatch, as communications increase and the number of messages increases, it is difficult for subcomponents to track which parent component the message listens to. If you do not pay attention, the last tracing of the game, want to be a lasting wonderful.

$dispatch and $broadcast have been deprecated in the vue2.0, and if you really want to stick with it, you can simulate it through $emit and change this via apply or call to facilitate recursion.

Communication between non-parent and child components 1. State management Scenario Vuex (recommended)

Suitable for complex data flow management. For detailed use, see the following site,

Https://github.com/vuejs/vuex

2. Central data bus (recommended for use in simple scenarios)

Create a separate empty Vue instance (events = new Vue ()) as an event transceiver that $emit on the instance, $on, $off, and so on. Application scenario: A. Use events. $on components do not care about the specific source of the event; b. There are no side effects (such as refreshes, queries, etc.) for event handlers to execute or repeat. As in example code 5,

"Sample Code 5"

<body><div id= "Apps" >    

  

Why is it only for simple scenarios? Vue's modular development pattern means that a component is likely to be instantiated multiple times. See below for an analysis

Suppose that the a component uses events. $emit (' event '), which is instantiated two times in the same interface, now requires that component A, instance 1, trigger the message ' event ' to be updated according to the message ' event ', component A instance 2 triggers the message ' event ', Component B cannot be updated as appropriate for the message ' event '. At this point, because component B is using events. $on (' event ') is not clear whether the message ' event ' is triggered by a component instance 1, or a component instance 2.

Therefore, when using this method, it is best to ensure that the component is rendered only once on the same interface, or that it does not need to be concerned about events. $emit which instance fires.

3. Passing attributes using the value of an object

Applicable scenario: In the list, you need to change the information for a particular piece of data. When a variable copies the value of a reference type to another variable, the copied value is actually a pointer to the same object stored in the heap.  Therefore, changing one of the variables will affect the other variable. For example, in a table list, how do you change the data for n row y columns in the n row x column?

"Instance Code 6"

<body><div id= "App" > <table> <tr> <th v-for= "title in Table.head" >{{title}           }</th> </tr> <tr v-for= "item in Table.data" > <td>{{item.name}}</td> <td><status:value= "Item.status" ></status></td> <td><t-switch:item= "it Em "> Toggle </t-switch></td> </tr> </table></div><script> vue.component (' Statu    S ', {Template: ' <span>{{value}}</span> ', props: {value: {}}});            Vue.component (' T-switch ', {Template: ' <button @click = ' switchstatus ' > Toggle Status </button> ', props: { Item: {}}, methods: {Switchstatus () {this.item.status = This.item.sta Tus = = = ' effective '?    ' Invalid ': ' Valid '}}); New Vue ({el: ' #app ', data: {table: {head: [' Ad name '], ' state ', ' operation '], data: []}, Ready () {var timer = setTimeout (() = = {This.table.data = [{name: ' adName1 ', Status: ' Invalid '}, {name: ' Adnam             E2 ', Status: ' Valid '}, {name: ' AdName3 ', Status: ' Invalid '}] cleartimeout (timer) }, (+)}) </script></body>

  

4. Observer mode

Https://github.com/vuejs/vue-rx

In short, whether it's vue1.0 or vue2.0, to ensure clear data flow and event flow, parent-child component communication follows the "props down, events up" principle. Non-parent-child components choose different scenarios based on different scenarios, and the VUEX state management scenario is still recommended in most cases.

————————————————————

There is only enough effort to look effortless!

Vue.js Communication between components

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.