vue responsive analytical principle

# Vue Responsive analytical principle

First we define the four core js file
- 1. observer.js observer function to get and set data set functions, and stored in the watcher in dep
- 2. watcher.js listener function is used to set dep.target open conditions depend collected, and triggered update function view
- 3. compile.js compiled by function, for compiling templates and watcher function instantiation
- 4. index.js entry file
Note dep function is a shell, used to store watcher watcher and trigger update
First, from the beginning index.js, defined functions SelfVue
```js
function SelfVue (options) {
Object.keys(this.data).forEach(function(key) {
self.proxyKeys(key);
// traverse data, a key to perform each function proxyKeys, definitions get, set
// This data may be acquired in the name value by the this.name
// otherwise have to get through this.data.name
});
// observation this.data, set up all kinds of listening rules; observe (this.data)
new Compile (options.el, this); // here compiled handlers and call the watcher
options.mounted.call (this); // everything is good to perform post-processing function mounted
}
```
Then look observe function:
```js
defineReactive: function(data, key, val) {
var dep = new Dep (); // initialize dep, dep used to store watcher
Object.defineProperty(data, key, {
get: function getter () {
// set Dep.target only if the watcher, a watcher so only in the monitor will go to increase
if (Dep.target) {//Dep.target is the preservation of their own Watcher
dep.addSub(Dep.target);
}
return val;
},
set: function setter (newVal) {
if (newVal === val) {
return;
}
val = newVal;
dep.notify();
}
});
}
```
Then look watcher
```js
function Watcher(vm, exp, cb) {
this.value = this.get (); // add themselves to the operation of subscriber
/*
Here execution this.get (), is called this.vm.data [this.exp]
That is called an observer in the get function:
First to Dep.target assignment, the observer function, open the
if (Dep.target) {
dep.addSub (Dep.target); // can be added to the watcher function in the herein dep
}
*/
}
Watcher.prototype = {
get: function() {
Dep.target = this; // cache yourself
var value = this.vm.data [this.exp] // enforcement listener in get function
Dep.target = null; // add to dep after, and then release their own
return value;
}
}
```
So each new watcher when it will instantiate watcher
Then will call this.value = this.get ();
Then it will execute this.vm.data [this.exp]
Will call the get method observer function, since this time set dep.target
So will save watcher in the dep
```js
new Watcher(this.vm, exp, function (value) {
self.updateText(node, value);
});

```
Let's look at compile.js is triggered when listening watcher function, the document does three things:
```js
this.fragment = this.nodeToFragment (this.el); // Get element is mounted snippet
this.compileElement (this.fragment); // this code fragment partition type, compile
this.el.appendChild (this.fragment); // This code fragment to mount the html
```
So the core code is compileElement function:
```js
[].slice.call(childNodes).forEach(function(node) {
var reg = /\{\{(.*)\}\}/;
each text = node.textContent;
if (self.isElementNode (node)) {// v-model instruction, v-on: click Method
self.compile(node);
} Else if (self.isTextNode (node) && reg.test (text)) {// text node
self.compileText(node, reg.exec(text)[1]);
}
if (node.childNodes && node.childNodes.length) {// child node continues to loop through
self.compileElement(node);
}
});
```
Loop through the template code, by: a text node, v-model instruction, v-on: click do different methods of logic:
However, this function will be used
```js
new Watcher(this.vm, exp, function (value) {
self.updateText(node, value);
});
```
As mentioned above, when instantiated Watcher, it is to give exp template used, to dep increase watcher function in
The method watcher functions include: Update and get functions.
So After traversing the template instantiation watcher, then it will get executed in the watcher function, to achieve the monitoring function.
```js
Watcher.prototype = {
update: function() {
var value = this.vm.data[this.exp];
var oldVal = this.value;
if (value !== oldVal) {
this.value = value;
this.cb.call(this.vm, value, oldVal);
}
},
get: function() {
Dep.target = this; // cache yourself
var value = this.vm.data [this.exp] // enforcement listener in get function
Dep.target = null; // release their own
return value;
}
};

```
---
When the data to be changed, it will trigger in the viewer function set function:
```js
set: function setter (newVal) {
if (newVal === val) {
return;
}
val = newVal;
dep.notify();
}
```
Then will notify dep update, here noted that if the value is not used in the template, this.sub is an empty array, so here notification function is not updated view:
```js
notify: function() {
// While all the above values ​​when data changes trigger set and dep.notify ();
// But here just will cycle through each before listening to the watcher --- this.subs
// So, if not used in html data, even if the methods are to
// here will not trigger update view
this.subs.forEach(function(sub) {
sub.update();
});
}

```

If the template data is used twice in the title:
<h2>{{title}}</h2>
<h1>{{title}}</h1>
After the data cycle variable for the title, there are two Watcher, exists for the data value: title of this.sub array.
So if you did not use in the template data, variables such as age,
In the set function, because the template is not used -> does not execute new Watcher -> will not be assigned to dep.target -> would not rely dep collection, the preservation watcher;
In the get function, because the template is not used, dep.sub array corresponding to the array is empty. So even if set function notifies the dep.notify function also should be empty array, will not lead to the execution cycle, it can not trigger an updated view of the function watcher

Guess you like

Origin www.cnblogs.com/xiaozhumaopao/p/12038895.html