Entrance to the file
When new Vue is executed, the _init() initialization method of instance\init.js is executed to initState, InitData will call proxy(VM, _data, key) mount data’s key to the Vue instance and call observe(data, True /* asRootData */) Do reactive processing reactive processing in SRC \core\observer\index.js
Start the process (just listing some code)
responsive
observe(value, asRootData)
- Determine if the value passed in is an object
- Whether responsive processing has been done
- Create a reactive property for this object
Function observe(value, asRootData) {return if (! IsObject (value) | | value instanceof VNode) {/ / have to judge the value __ob__ attribute the if (hasOwn (value, '__ob__) && value. __ob__ instanceof Observer) / / or whether object or Array else if (Array. IsArray (value) | | isPlainObject (value)) { Ob = new Observer(value)}}Copy the code
Constructor creates a dependency collection Dep for the current object value. Mount the current Observer instance to value’s __ob__. The notification is published and the reactive processing object is traversed and processed reactive for each property
Def (value, '__ob__',) {constructor(value, '__ob__'); If (array.isarray (value)); if (array.isarray (value)); // The object calls walk to iterate over each property and convert to getter and setter this.walk(value)}Copy the code
DefineReactive (obj, keys[I]) for each attribute in walk object.keys ()
defineReactive(obj, keys[i])
- Create Dep collection dependencies for properties
- Determines whether children of recursive attributes are needed
- Define getters and setters for properties
- getter
- Check if there are targets and collect dependencies if there are
- Then determine whether there are children and collect dependencies for them
- If the child object is an array, it iterates through the array elements to collect dependencies
- setter
- Determine whether the value has changed
- If the new value is changed, then determine whether the new value is an object
- If it is an object, it does reactive processing for that object
- Publish notification updates for the current property
defineReactive(obj, Key) {// Create attribute dep const dep = new dep () val = obj[key] // Determine whether a recursive child object is required. Observe processes only the object, even if its shallow is true if val is not an object Return false in Observe let childOb =! shallow && observe(val) Object.defineProperty(obj, key, { get: Function () {// If there is target (Watcher) if (dep.target) {dep.depend() // If there is a child object that has __ob__ also collect the dependency if (childOb) {// DependArray (value)}}}}, set: dependArray(value) {if (array.isarray (value)) dependArray(value)}}}}, set: ChildOb =! Function (newVal) {// If the new value is an object, childOb =! Shallow && observe(newVal) // Notify dep.notify()}})}Copy the code
Reactive – Collect dependencies
SRC \ Core \observer\watcher. Js is a file created by new Watcher, The $mount execution will create a render Watcher, and the dependency collection will be completed when _render generates the Vnode. In this process, Watcher and Dep will record each other Watcher constructor calls get() and pushTarget(this)
Function pushTarget (target) {// Put the current Watcher instance on dep.target dep.target = target}Copy the code
Generate a node to access a property in the template, triggering the getter for the property
// Call Watcher's addDep() dep.target.adddep (this)}Copy the code
AddDep (dep) {const id = dep.id // this.newDepIds will record whether the current deP has been collected. This.newdepids.has (id)) {// Watcher records Dep this.newdepids.add (id) this.newdepids.push (Dep) if (! This.depids. has(id)) {// call dep to collect dep.addSub(this)}}}Copy the code
// Add a new subscriber watcher object addSub (sub) {this.subs.push(sub)}Copy the code