手動實現乙個vue的mvvm,思路解析

2022-09-07 12:27:09 字數 3962 閱讀 4259

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 通過...