English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

From Usage to Source Code Implementation Tutorial of Vue, an In-depth Explanation

Build environment

Project GitHub address

The project involves json-Server simulation of get request, used vue-router;

About Vue lifecycle and vue-router hook function details

Lifecycle

1.Version 0

1.What are the lifecycle interfaces

init
Created
beforeCompile
Compiled
Ready
Attatched
Detached
beforeDestory
destoryed

2. Execution order

1. Does not have keep-alive

Enter:

init->create->beforeCompile->complied->attatched->ready

Remove:

beforeDestory->detached->destoryed;

2. Has keep-alive

The first time

Enter:

init->create->beforeCompile->complied->attatched->ready

Remove:

detached;

After each time

Enter:

attatched

Remove:

detached

Hook functions

3. What hook functions are there

data
activete
deactivate
canactivate
candeactivate

4. Execution order

Enter:

canactivate->actiavte->date

Remove:

candeactivate->deactiavte

Both appear together

5. For a component A with a child component B, when this component A performs entering and exiting operations, the execution order of the components and hook functions can be referred to as follows:

For example

A.vue

<div>
<B></B>
</div>

Note: The items in the parentheses below are nested child components

1. Does not have keep-alive:

Enter:

1canActivate;
2init;
3create;
4beforeCompile;
5(Nested child component: init, create, beforeCompile, compile);
6compile;
7activate;
8data;
9attached;
10(Child component attached);
11(Child component ready);
12ready;

Remove:

13canDeactivate;
14deactivate;
15beforeDestroy;
16(Child component beforeDestroy);
17(Child component destoryed);
18detached;
19(Child component detached);
20. destoryed;

2. Has keep-alive:

Enter:

1canActivate;
2activate;
3data;
4attached;
5(Child component attached);

Remove:

6canDeactivate;
7deactivate;
8detached;
9(Child component detached);

6Execution order of hook functions activate and data

Rules for the asynchronous resolution of hook functions:

1If the hook returns a Promise, when the hook resolves depends on when the Promise resolves.

2If the hook neither returns a Promise nor has any parameters, the hook will be resolved synchronously.

3If the hook does not return a Promise but has a parameter (transition), the hook will wait until one of transition.next(), transition.abort(), or transition.redirect() is called to resolve.

4.In the verification class hooks, such as canActivate, canDeactivate, and global beforeEach hooks, if the return value is a boolean (Boolean), it will also cause the hook to resolve synchronously.

 
 

7.What ensures that the interface has been updated, that is, it has been mounted

Execution of lifecycle attached indicates that it has been mounted

Two-way binding and rendering mechanism

1.data listening and triggering (subscription and publishing observer)

src directory under observer:

1. array.js

2. dep.js;(Implementing a publish-subscribe object)

3. index.js;(Using the Object.defineProperty API, and designing a special getter for this property)/Then trigger a function in the setter to achieve the effect of listening);

The source code for this part is as follows:

Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
var value = getter ? getter.call(obj) : val
if (Dep.target) {
dep.depend()
if (childOb) {
childOb.dep.depend()
}
if (isArray(value)) {
for (var e, i = 0, l = value.length; i < l; i++) {
e = value[i]
e && e.__ob__ && e.__ob__.dep.depend()
}
}
}
return value
},
set: function reactiveSetter (newVal) {
var value = getter ? getter.call(obj) : val
if (newVal === value) {
return
}
if (setter) {
setter.call(obj, newVal)
} else {
val = newVal
}
childOb = observe(newVal)
dep.notify()
}
})}}

The simplified code for the listening and triggering is as follows:

function notidy(obj,key){
console.log(key+has changed
console.log(key+" now is: "+obj[key]);
}
function ToData(key,val){
var ob=this;
Object.defineProperty(ob,key,{
enumerable:true,
configurable:true,
get:function(){
return val;
},
set:function(newval){
if(newval==val){
return;
}
val=newval;
notidy(this,key);
}
})}}
}

src directory under directive.js

In the directive, you can see a series of parsed properties, and the instantiation of the directive can be found in utils/seen in lifecycle.js.

The following code is in Directive.prototype._bind

var watcher = this._watcher = new Watcher(
this.vm,
this.expression,
this._update, // callback
{
filters: this.filters,
twoWay: this.twoWay,
deep: this.deep,
preProcess: preProcess,
postProcess: postProcess,
scope: this._scope
}
)
// v-model with inital inline value need to sync back to
// model instead of update to DOM on init. They would
// set the afterBind hook to indicate that.
if (this.afterBind) {
this.afterBind()
} else if (this.update) {
this.update(watcher.value)
}
Directive.prototype.set = function (value) {
/* istanbul ignore else */
if (this.twoWay) {
this._withLock(function () {
this._watcher.set(value)
})}}
} else if (process.env.NODE_ENV !== 'production') {
warn(
'Directive.set() can only be used inside twoWay' +
'directives.'
)
}
}

src directory under Watch.js:

The watcher object implements subscription through the addDep method can be found from the following code

Watcher.prototype.addDep = function (dep) {
var id = dep.id
if (!this.newDepIds.has(id)) {
this.newDepIds.add(id)
this.newDeps.push(dep)
if (!this.depIds.has(id)) {
dep.addSub(this)
}
}
}

2As mentioned above about two-way binding, in fact, this is also the rendering mechanism inside VUE, summarized as follows

1The data is monitored through observer, and the ability to subscribe to changes in a data item is provided

2The template is parsed into a document fragment, and then the directive in it is parsed to get the data item and update method that each directive depends on. For example, v-After the 'text="message"' is parsed (here is for illustration only, and the actual program logic will be more rigorous and complex): the data item this.$data.message that depends on, as well as the corresponding view update method node.textContent = this.$data.message

3By using watcher, the above two parts are combined, that is, the data dependency subscription in directive is on the corresponding observer of the data, so when the data changes, it will trigger observer, and then trigger the corresponding view update method of the dependent view, and finally achieve the original association effect of the template.

3How has '.vue' improved 'v'-Why does rendering with the same data fail in 'for'?

Array rendering

No track used-The default id for the internal cache of array rendering in 'by' is the value of the array, meaning that if there are duplicate values in the array, the same fragment fragment is obtained through id, and the DOM operation insertBefore does not take effect due to the same instance.

<div>
<ul id='test'>
<li id="child1">child</li>1</li>
<li id="child">child2</li>
</ul>
</div>
<script>
_element1=document.getElementById('child1);
_element2=document.getElementById('child2);
document.getElementById('test').insertBefore(_element1,_element2);
</script>

The rendering result is child2In child1Previous

Using track-The purpose of by is to customize this internal id so that several items with the same values in the array will not select the same instance, for using track-There are some differences between by='$index' and other unique distinguishing id values, each has its own advantages.

Using $index makes the reversed data without moving operations, while for using other ids in different orders, there will be corresponding moving operations.

Rendering of Objects

Objects generally use keys as the internal cache object id, through track-by can also customize this id to improve performance.

vm.model = {
a: { id: 1, val: "model"1},
b: { id: 2, val: "model"2},
c: { id: 3, val: "model"2},
}

List Update

vm.model = {
d: { id: 1, val: "model"1},
e: { id: 2, val: "model"2},
f: { id: 3, val: "model"2"}
}

The above is the detailed tutorial from usage to source code implementation of vue introduced by the editor for everyone, hoping it will be helpful to everyone. If you have any questions, please leave a message, and the editor will reply to everyone in time. Thank you very much for everyone's support for the Yelling Tutorial website!

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 for reporting. Provide relevant evidence, and once verified, this site will immediately delete the infringing content.)

You May Also Like