1、解析dom、fragment編譯,初始化new watcher
2 ,資料劫持,object.defineproperty(obj,key,, // 新增wacher,新增訂閱者
set:function(newvalue) // noticfy:執行,更新資料
3, 發布訂閱模式:
什麼是發布訂閱者模式呢?舉個例子:大爺我要傳授們手藝,我這裡收了很多徒弟,為了節約時間,我將他們記錄在我的郵件裡,等我準備好資料,在我這裡留底的人員進行**
接下裡開始**實現的過程
1,建立乙個簡單的應用,
>
type="text"
v-model="word"
>
}p>
v-on:click="sayhi"
>change modelbutton>
div>
src="./js/observer.js"
>script>
src="./js/watcher.js"
>script>
src="./js/compile.js"
>script>
src="./js/mvvm.js"
>script>
var vm =
newmvvm(,
methods:
}});
script>
2,我們先初始化將模板中的 }替換,建立compile函式進行編譯,替換
function
mvvm
(options
)
3,我們要開始實現我們的compile函式function
compile(el, vm)
}compile.prototype =
return
fragment;
},init
:function() ,
compileelement
:function(el) \}
/;if (me.iselementnode(node)) else
if (me.istextnode(node) && reg.test(text))
if (node.childnodes && node.childnodes.length)
});},
compile
:function(node) else
node.removeattribute(attrname);
}});
},compiletext
:function(node, exp) ,
isdirective
:function(attr) ,
iseventdirective
:function(dir) ,
iselementnode
:function(node) ,
istextnode
:function(node)
};// 指令處理集合
varcompileutil = ,
html
:function(node, vm, exp) ,
model
:function(node, vm, exp)
me._setvmval(vm, exp, newvalue);
val = newvalue;
});},
class
:function(node, vm, exp) ,
bind
:function(node, vm, exp, dir) );
},// 事件處理
eventhandler
:function(node, vm, exp, dir)
},_getvmval
:function(vm, exp) );
return
val;
},_setvmval
:function(vm, exp, value) else
});}
};var
updater = ,
htmlupdater
:function(node, value) ,
classupdater
:function(node, value, oldvalue) ,
modelupdater
:function(node, value, oldvalue)
};function
watcher(vm, exporfn, cb) ;
if (typeof
exporfn === 'function') else
this.value = this.get();
}watcher.prototype = ,
run:
function()
},adddep
:function(dep) 改變了 child.name 的值,child.name 就是個新屬性
// 則需要將當前watcher(child.name)加入到新的 child.name 的dep裡
// 因為此時 child.name 是個新值,之前的 setter、dep 都已經失效,如果不把 watcher 加入到新的 child.name 的dep中
// 通過 child.name = *** 賦值的時候,對應的 watcher 就收不到通知,等於失效了
// 4. 每個子屬性的watcher在新增到子屬性的dep的同時,也會新增到父屬性的dep
// 監聽子屬性的同時監聽父屬性的變更,這樣,父屬性改變時,子屬性的watcher也能收到通知進行update
// 這一步是在 this.get() --> this.getvmval() 裡面完成,foreach時會從父級開始取值,間接呼叫了它的getter
// 觸發了adddep(), 在整個foreach過程,當前wacher都會加入到每個父級過程屬性的dep
// 例如:當前watcher的是'child.child.name', 那麼child, child.child, child.child.name這三個屬性的dep都會加入當前watcher
if (!this.depids.hasownproperty(dep.id))
},get
:function() ,
parsegetter
:function(exp)
return
obj;}}
};實現observe
function
observer(data)
observer.prototype = );
},convert
:function(key, val) ,
definereactive
:function(data, key, val)
return
val;
},set
:function(newval)
val = newval;
// 新的值是object的話,進行監聽
childobj = observe(newval);
// 通知訂閱者
dep.notify();
}});}};
function
observe(value, vm)
return
newobserver(value);
};var
uid = 0;
function
dep()
dep.prototype = ,
depend
:function() ,
removesub
:function(sub)
},notify
:function() );}};
dep.target = null;
整體實現此路,需要一張圖演示實現思路
mvvm實現乙個簡單的vue
vue,基於mvvm模式下的乙個前端框架 mvvm模式下簡單的實現資料 資料劫持 1.是用object.defineproperty 實現資料 2.使用發布訂閱者模式,配合 object.defineproperty,實現資料劫持 資料劫持包括依賴收集和依賴促發 只考慮最簡單的方式,並且沒有包括具體...
實現乙個mvvm
最近在團隊內做了一次vue原理分享,現場手寫了乙個乞丐版mvvm,這裡記錄一下這個mvvm實現的過程。原始碼 這個mvvm是基於發布訂閱模式實現 也是vue本身的實現原理 最終達到的效果如下 使用方式也跟vue一樣 重置 實現很簡單 class mvvm options this.methods m...
自己動手實現乙個MVVM庫
我們知道的,常見的資料繫結的實現方法 1 資料劫持 vue 通過object.defineproperty 去劫持資料每個屬性對應的getter和setter 2 髒值檢測 angular 通過特定事件比如input,change,xhr請求等進行髒值檢測。3 發布 訂閱模式 backbone 通過...