This article mainly introduces how to implement props bidirectional binding in Vue2, which has some reference value. If you are interested, refer to Vue Study Notes-3 preface.
Compared with Vue 1. x, Vue 2. x not only implements Virtual-Dom, but also provides the props bidirectional binding function of the removed component.
In the past, Vue1.x used props twoWay and. the props bidirectional binding function can be implemented by using the sync binding modifier, but this function is completely discarded in Vue2. You need to implement this function if you need bidirectional binding.
Props communication mode of Vue2 Components
In Vue2, the props Data Flow of the component is changed to only one-way flow. That is, the props can only be passed to the component through the DOM attribute of the component outside the component, the component can only passively receive data transmitted from external components. In the component, the props data transmitted from the outer layer cannot be modified.
The code is roughly like this:
// Switch component code Vue. component ("switchbtn", {template :"{Result? 'Callback': 'callback '}}
", Props: [" result "], methods: {change () {this. result =! This. result ;}}); // call the new Vue ({el: "# app", data: {result: true // switch status data}, methods: {change () {this. result =! This. result ;}}});
However, when the above Code in vue2.0 is clicked:
[Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. instead, use a data or computed property based on the prop's value. prop being mutated: "result" (found in component)
The props value cannot be modified in the component, and the modified value is not synchronized to the outer layer of the component. That is, the caller does not know the current status of the component.
Bind component attributes in Vue2.0 in two-way
1. Create a copy of the props attribute in the data Object of the component.
Because the result cannot be written, you need to create a copy of myResult variable in data. The initial value is the value of result in the props attribute, and call the data Object myResult in all the places in the component that need to call props.
Vue. component ("switchbtn", {template :"{MyResult? 'Callback': 'callback '}}
", Props: [" result "], data: function () {return {myResult: this. result // Add a field};},...} in data };},......});
2. Create a watch for the props attribute to synchronize modifications to the props outside the component
The props of the component modified outside the component (parent component) will be synchronized to the corresponding props in the component, but will not be synchronized to the copy you just created in the data object, therefore, you need to create another watch (listener) for the result of the props attribute. After the props is modified, the copy of the corresponding data, myResult, also needs to synchronize data.
Vue. component ("switchbtn", {template :"{MyResult? 'Callback': 'callback '}}
", Props: [" result "], data: function () {return {myResult: this. result };}, watch: {result (val) {this. myResult = val; // watch the new result, listen for changes and synchronize them to myResult }},......
3. Create a watch for the props copy to notify the outside of the component
At this time, the copy of props myResult is modified in the component, and the props status in the component is unknown outside the component. Therefore, you need to create another copy of myResult for props, that is, watch corresponding to the data attribute.
Send a notification to the outer component (parent component) to notify the component of attribute changes, and then the outer component (parent component) changes its data.
All final code:
Vue. component ("switchbtn", {template :"{MyResult? 'Callback': 'callback '}}
", Props: [" result "], data: function () {return {myResult: this. result // ① create a copy of result in the props attribute -- myResult};}, watch: {result (val) {this. myResult = val; // ② listen to external changes to the result of the props attribute and synchronize it to the data property myResult in the component}, myResult (val) {// xxcanghai this. $ emit ("on-result-change", val); // send Event Notifications to external users after myResult is changed in the component}, methods: {change () {this. myResult =! This. myResult ;}}); new Vue ({el: "# app", data: {result: true}, methods: {change () {this. result =! This. result;}, onResultChange (val) {this. result = val; // ④ the external caller registers the change method and synchronizes the data changes in the component to the data status outside the component }}});
At this point, the data in the component is bound to the data outside the component, and the data inside and outside the component is synchronized. The last sentence is: The component itself has changed to tell the external, the external decide whether to change.
Example:
Import propsync from '. /mixins/propsync '; // introduce the mixin File export default {name: "tab", mixins: [propsync], // declare the mixin props: {active: {type: [String, Number], // it will be automatically bound in two directions by propsync. Create p_active variable}, width: {type: [Number, String], propsync: false // two-way binding will not be implemented by propsync}, methods: {setActive (page, index, e) {this. p_active = index; // you can use this directly. p_active }}}
Call Components
After propsync is introduced, an onPropsChange event is triggered after the data changes to the internal two-way binding. Then, an event listener onPropsChange (which can be modified) is added to the call component. When props is modified in the component, propsync will trigger this event. The returned results are as follows: Modify the prop name, the value after modification. The value before modification. The current component caller (parent component) can determine whether to synchronize changes in the component to the caller.
Example:
...... Slightly {data: {active: 0}, methods: {change: function (propName, newVal, oldVal) {this [propName] = newVal; console. log ("component tab" + propName + "attribute changed to" + newVal );}}}
For more Vue2 implementation component props two-way binding related articles, please follow the PHP Chinese network!