initCreatedbeforeCompileCompiledReadyAttatchedDetachedbeforeDestorydestoryed2.执行顺序
7.根据什么可以确保界面已经更新完成,也就是说挂在完成
执行生命周期attached说明已挂载
双向绑定与渲染机制
1.数据的监听和触发(订阅和发布observer)
src目录下observer:
1. array.js
2. dep.js;(实现一个发布订阅对象)
3. index.js;(利用Object.defineProperty这个API,并为此属性设计一个特殊的 getter/setter,然后在 setter 里触发一个函数,达到监听的效果);
下面是这部分的源码
Object.defineProperty(obj, key, {enumerable: true,configurable: true,get: function reactiveGetter () {var value = getter ? getter.call(obj) : valif (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) : valif (newVal === value) {return}if (setter) {setter.call(obj, newVal)} else {val = newVal}childOb = observe(newVal)dep.notify()}})简化上面的监听与触发代码如下:
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目录下directive.js
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目录下Watch.js:
Watcher.prototype.addDep = function (dep) {var id = dep.idif (!this.newDepIds.has(id)) {this.newDepIds.add(id)this.newDeps.push(dep)if (!this.depIds.has(id)) {dep.addSub(this)}}}2.前面说那么多关于双向绑定,其实这也是VUE内部的渲染机制,总结如下
<div><ul id="test"><li id="child1">child1</li><li id="child">child2</li></ul></div><script>_element1=document.getElementById("child1");_element2=document.getElementById("child2");document.getElementById("test").insertBefore(_element1,_element2);</script>渲染的结果是child2在child1前面
vm.model = {a: { id: 1, val: "model1"},b: { id: 2, val: "model2"},c: { id: 3, val: "model2"},}列表更新
vm.model = {d: { id: 1, val: "model1"},e: { id: 2, val: "model2"},f: { id: 3, val: "model2"}}以上所述是小编给大家介绍的vue从使用到源码实现教程详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!