English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Introduction
Observer is the most important module in Vue core (I think), which can realize the reactive update of view and data, and relies entirely on the support of observer.
Note:This article is for [email protected]
The code location of observer module in Vue project is src/core/The observer module is divided into these parts:
The illustration is as follows:
Observer
Observer class is defined in src/core/observer/Let's take a look at the constructor of Observer in index.js first
constructor (value: any) { this.value = value this.dep = new Dep() this.vmCount = 0 def(value, '__ob__', this) if (Array.isArray(value)) { const augment = hasProto ? protoAugment : copyAugment augment(value, arrayMethods, arrayKeys) this.observeArray(value) } this.walk(value) } }
value is the data object to be observed. In the constructor, the __ob__ property will be added to value as a flag indicating that the data has been observed by Observer. If value is an array, use observeArray to traverse value and observe each element of value individually. If value is an object, use walk to traverse each key on value and use defineReactive to obtain the set of each key/get control.
Here is an explanation of the functions used above:
If the above text description is not understood, you can see the figure below:
Dep
Dep is the link between Observer and Watcher, and can also be considered as the subscription system serving Observer. Watcher subscribes to the Dep of an Observer, and when the data observed by the Observer changes, it notifies all subscribed Watchers through Dep.
Dep provides several interfaces:
Watcher
Watcher is used to subscribe to data changes and execute corresponding operations (such as updating the view). The constructor function of Watcher is defined as follows:
constructor (vm, expOrFn, cb, options) { this.vm = vm vm._watchers.push(this) // options if (options) { this.deep = !!options.deep this.user = !!options.user this.lazy = !!options.lazy this.sync = !!options.sync } this.deep = this.user = this.lazy = this.sync = false } this.cb = cb this.id = ++uid // uid for batching this.active = true this.dirty = this.lazy // for lazy watchers this.deps = [] this.newDeps = [] this.depIds = new Set() this.newDepIds = new Set() this.expression = process.env.NODE_ENV !== 'production' ? expOrFn.toString() : '' if (typeof expOrFn === 'function') { this.getter = expOrFn } this.getter = parsePath(expOrFn) if (!this.getter) { this.getter = function () {} process.env.NODE_ENV !== 'production' && warn( `Failed watching path: "${expOrFn}" ` + 'Watcher only accepts simple dot-delimited paths. ' + 'For full control, use a function instead.', vm ) } } this.value = this.lazy ? undefined : this.get() }
In the parameters, vm represents the component instance, expOrFn represents the data field to be subscribed (a string, such as a.b.c) or a function to be executed, cb represents the callback function after the watcher runs, and options is the option object, which includes configurations such as deep, user, lazy, etc.
The watcher instance has these methods:
Array methods
In src/core/observer/In array.js, Vue framework has modified the push, pop, shift, unshift, sort, splice, reverse methods of arrays, which will automatically trigger dep.notify() when calling these methods of the array, solving the problem that the update cannot be triggered after calling these functions to change the array.
There is also an explanation of this in the official Vue documentation: http://cn.vuejs.org/v2/guide/list.html#mutation-methods
Summary
That's all the content of this article. I hope the content of this article can bring some help to everyone's learning or work. If you have any questions, you can leave a message for communication.
Statement: The content of this article is from the Internet, and the copyright belongs to the original author. The content is contributed and uploaded by Internet users spontaneously. This website does not own the copyright, has not been manually edited, and does not assume any relevant legal liability. If you find any content suspected of copyright infringement, please send an email to: notice#oldtoolbag.com (Please replace # with @ when sending an email to report abuse, and provide relevant evidence. Once verified, this site will immediately delete the infringing content.)