Foreword
Read this section, we need to understand the data driving principle of vue.
Look at this piece of code
new Vue({ data: { msg: 'hello', say: 'hello world', }, watch: { msg(newVal) { this.say = newVal + ' world'; } } })
The data includes two vue msg attributes and say, watch the monitor and updates the value of say msg.
Source code implementation
1. new view
function Vue (options) { if ("development" !== 'production' && !(this instanceof Vue) ) { warn('Vue is a constructor and should be called with the `new` keyword'); } this._init(options); }
new Vue will perform _init method on the prototype, _init method hi call initState, this method will initialize all state-related content
2. initWatch
initStatus will determine if we define watch the execution initWatch
function initWatch (vm, watch) { for (var key in watch) { var handler = watch[key]; if (Array.isArray(handler)) { for (var i = 0; i < handler.length; i++) { createWatcher(vm, key, handler[i]); } } else {
createWatcher(vm, key, handler); } } }
This code means that if the watch declare an array, then loop through the array and call createWatcher, if not directly call createWatcher array passed in the past. This proves, watch we can declare multiple handlers.
3. createWatcher
createWatcher main job is to process the incoming value, passing different values, doing different treatment compatible
function createWatcher ( VM, expOrFn, handler, Options ) { // If the handler is an object, obtaining the following handler handler attribute watch function is executed as IF (isPlainObject (handler)) { Options = handler; handler = handler.handler; } // If the handler is a string, the method for obtaining vue prototype IF ( typeof handler === 'string' ) { handler = VM [handler]; } // $ Watch calls on vue prototype return VM $ Watch. (expOrFn, Handler, Options) }
Through the above we can see, watch definitions There are many types, such as:
new new Vue ({ Watch: { // string test1: 'handleTest' , // Object test2: { Handler (newVal) { // .... } } }, Methods: { handleTest (newVal) { // .. . } } })
4. vm.$watch
Vue.prototype.$watch = function ( expOrFn, cb, options ) { var vm = this; if (isPlainObject(cb)) { return createWatcher(vm, expOrFn, cb, options) } options = options || {}; options.user = true; // new 一个Watcher实例 var watcher = new Watcher(vm, expOrFn, cb, options); if (options.immediate) { cb.call(vm, watcher.value); } return function unwatchFn() { watcher.teardown(); } };
As can be seen by the above code, we watch the final creation is actually created an internal vue Watcher instance. Well Watcher is a very important part of vue, it is a data-driven indispensable part.
Then probably talk about the new Watcher feature is what.
5. new Watcher
vue in getting the function to listen attributes and update the implementation of, new Watcher create a Watcher.
Watcher is a subscriber, it "listens update behavior" and perform the update function.
Why double quotation marks? In fact, it is not listening. In an example the original code update is as follows:
Internal 1. vue new Watcher Watcher create an instance of
2. Watcher instance will create its own when added to the Observer data.msg in (data-driven knowledge of the principles)
3. When we change the value of msg, msg Observer will notify all observers, including more than Watcher. (Principles of data-driven knowledge)
4. Watcher trigger and update callback, so we execute the function declaration.
end
watch implementation is very simple, there needs vue data-driven principles, implemented by Object.defileProperty, Dep, Watcher several parts. Do not understand can go to learn this part.