The core and basic API of Vue two-way data binding is Object.defineProperty. The main internal participants in the two-way data binding process are Obderver, Dep and Watcher. Based on defineProperty and publisher subscriber mode, the two-way data binding is finally realized. So how exactly do Obderver, Dep, and Watcher work together? Let’s take a look.

Before reading this article, you need to have some understanding of vUE’s two-way data binding. Js source code interpretation series – how does bidirectional binding initialize and work

This should give you an understanding of two-way data binding:

Note: to understand this article you need to have a certain understanding of THE Vue MVVM, and need to focus on understanding, or follow the source code, otherwise it is difficult to really understand.

Two-way data binding is divided into two flows here:

1. Dependency collection process:

observe -> 
walk -> 
defineReactive -> 
get -> 
dep.depend() -> 
watcher.addDep(new Dep()) -> 
watcher.newDeps.push(dep) -> 
dep.addSub(new Watcher()) -> 
dep.subs.push(watcher)Copy the code

The dependency collection will go through the above process, and eventually the watcher. NewDeps array will hold the DEP list, and the dep.subs array will hold the Watcher list.


Why do you need dependency collection?

new Vue({
    data() {return {
             name:'zane',
             sex:'male'}}})Copy the code

If we set this.sex=’ female ‘, then Vue will perform a virtual DOM comparison, which will waste some performance. So you need to do dependency collection, interface used to collect, not used to collect.

We follow the process to deal with the source code:

Go directly to object.defineProperty’s get method:



It’s time to test your closures, and this DEP object is a closure. Take a look at the implementation of dep.depend().



Dep. Target is a Watcher instantiation object. If you want to know where it is assigned, please follow the code below.







Now that you know that dep. target is equal to a Watche object, let’s go back and see what watcher.adddep does.





So rely on the collection process is finished, whether it feels very round.

Conclusion: The dependency collection finally pushes the DEP object passed in the closure in Watcher. NewDeps and initializations in dep.subs. Vue is the watcher object of the resume. This. Getter = expOrFn, expOrFn is the core step of later data update page rendering, need to be carefully analyzed.


2. View update process:

set -> 
dep.notify() -> 
subs[i].update() -> 
watcher.run() || queueWatcher(this) -> 
watcher.get() || watcher.cb -> 
watcher.getter() -> 
vm._update() -> 
vm.__patch__()Copy the code

View update will go through the above process, and finally call Vue’s virtual Dom diff process to update the interface view in real time













After going to this point I will not go to the trace, after the call to vm.__patch__ method, and then perform the virtual DOM diff process real-time update interface.


Conclusion:

To have a good understanding of VUE data two-way binding will be more patient, sink down to slowly understand, but also need to have a general understanding of vUE source code, otherwise you will only see more and more irritable more and more no confidence.

Vue makes good use of the get and set methods of Object.defineProperty method, the design ideas of subscribers and publishers, and the clever organization code, which are worth our in-depth study and understanding, so as to urge us to use it better. Thanks to iu’s dedication, we have increased productivity and put more effort into business logic.

Original address: github.com/wangweiange…