1120 MVVM框架是如何實現雙向資料繫結剖析。

2021-09-11 10:54:55 字數 2651 閱讀 8715

思路:

1.model影響檢視:編譯時註冊watcher,在註冊watcher,呼叫get,通過observer資料劫持get方法,將多個觀察者統一管理起來。當改變資料時,呼叫set方法,將收攏的對應觀察者的upadte方法更新。

2.檢視影響model:編譯時註冊wather,node節點繫結對應的事件,事件觸發時,更改資料模型。

複製**

js模擬實現mvvm

mvvm.js,集中統一;供外呼叫;

class

mvvm

}//將data的屬性掛載到例項上,這樣就可以取this.***了l

proxydata(data),

set(newval)

})})

}}複製**

observe.js,資料劫持;收攏watcher統一管理;通知watcher更新;
class

observer()

//資料劫持(這裡我們只處理物件{}的監聽)

observe(data)

if(!data || object.prototype.tostring.call(data) !='[object object]');

object.keys(data).foreach(key=>)

}//資料響應式 defineproperty

definereactive(obj,key,value),

set(newvalue)}})

}}//觀察者模式,統一對watcher進行管理

class

dep()

//新增watcher

addsub(watcher)

//通知所有watcher更新

notify())

}}複製**

compile.js,元素和資料進行編譯,首次渲染檢視;建立watcher,定義資料變化後如何更改檢視;繫結事件,定義檢視變化如何更改model
class

compile

},替換成model對應的資料;建立watcher,定義資料更新如何更新;繫結事件,定義檢視變化如何更改model;

this.complile();

//3.把編譯好的fragment放回頁面中}}

/*輔助方法*/

//驗證是不是node節點

iselementnode()

//驗證是不是指令

iddirective(name)

/*核心方法*/

//將真實dom轉移到記憶體中,fragment,真實dom就不存在了;

node2fragment(el)

return fragment;

}//遞迴編譯

compile(fragment)else })}

//編譯元素節點

compileelement(node),1:}

array.from(attrs).foreach(attr=>})}

//編譯文字節點

compiletext(node)}} ; }

let reg = /\]+)}\}/g;

//判斷是不是 包含}表示式

if(reg.test(expr))

}}compileutil = ,vm.$data)

}//文字節點的內容進行編譯

gettextval(vm,expr)}};} 多種文字方式

let reg = /\]+)}\}/g;

return expr.replace(reg,(...args)=>)

}//修改例項上的資料

setval(vm,expr,value)

return prev[next]

},vm.$data)

}//輸入框處理 v-mode

model(node,vm,expr))

//繫結事件,檢視變化 影響資料

node.addeventlistener('input',(e)=>)

}//文字處理

//expr=> 例如}} ; } 考慮多種文字方式

text(node,vm,expr)]+)}\}/g;

expr.replace(reg,(...args)=>}}這種文字節點,其中乙個改變就需要將該文字節點渲染一次,就需要重新根據expr }}去重新渲染整個文字節點,所以用的是this.gettextval(vm,expr),而不是newvalue;

updatefn && updatefn(node,this.gettextval(vm,expr));

})})

}updater:

//輸入框更新

modelupdater(node,value)

}}複製**

watcher.js ,建立觀察者,編譯過程中每遇到乙個表示式或者v-model指令,就建立乙個觀察者。 每乙個資料 對應多個觀察者
calss watcher

getval(vm,expr),vm.$data)

}get()

//對外報漏的方法,當資料發生改變在observer set方法中,會呼叫sub的notify方法,nofity方法將所有watcher執行update方法

update()

}}複製**

Vue 實現mvvm框架

observe obj 訂閱 key 資料 if this.binding key let binding this.binding key 重寫getter,setter object.defineproperty obj,key,set newval proxydata data,vm set ...

仿照vue實現簡易的MVVM框架(二)

實現文字插值與s for迴圈模版。對於文字插值的實現,我採用正則去匹配還原這個dom節點,以插值 形式為分界,將這個dom節點的文字分割成多個字串,儲存在this.muscha中,再者,將普通文字字串以陣列形式儲存在string屬性中,將插值存放在text屬性值。當然,拼接的時候要明白先從strin...

仿照vue實現簡易的MVVM框架(一)

主要的方法有 compile 深度遍歷前端介面的節點,將其複製進乙個addquene佇列中 pasers 遍歷所有的節點,並將節點包裝成乙個含有本節點 自定義屬性及屬性值的物件。要想實現雙向繫結,重要的一步是,為自定義s model的節點繫結事件 input框的雙向繫結,監聽oninput事件 ob...