github.com/logictuLuoq…javascript
MVVM是Model-View-ViewModel的簡寫 MVVM 就是將其中的View 的狀態和行爲抽象化,讓咱們將視圖 UI 和業務邏輯分開。固然這些事 ViewModel 已經幫咱們作了html
你控制 Model(數據)
寫vue 全在控制數據
View(模板)
你就理解成 你寫的templeat
ViewModel這東西叫vuevue
咱們還記得react是這麼操做的嗎java
setData()累吧node
vue採用的是雙向數據綁定 是什麼呢 this.data簡單吧react
我寫完了雙向數據綁定 應爲中文名的緣由取名爲mvvmgit
git clone https://github.com/logictuLuoqi/Practice
cd MVVM
npm install serve
serve .
複製代碼
就跑起來了 爲何要用 serve 是這樣的本次代碼採用 ES6的模塊化github
<div id="app">
<input type="text" id="a" v-model="text">
{{ text }}
</div>
複製代碼
去寫 MVVM的jsnpm
new Vue({
el: 'app',
data: {
text: 'Hello Vue!'
}
})
複製代碼
observer(data, this);
const dom = new Compile(document.querySelector(`#${el}`), this);
複製代碼
針對於這兩個點作一下解釋bash
我去這個名字也知道作什麼了 雙向數據綁定 這裏採用 defineProperty
幫助理解observer中的defineProperty
get() {
if (Dep.target) {
dep.addSub(Dep.target);
}
return val;
},
set(newVal) {
if (newVal === val) return;
val = newVal;
dep.notify();
},
複製代碼
這裏的 Dep.target後續介紹
dep.notify();後續解釋
我在這裏寫的是createDocumentFragment 來代替虛擬dom這東西后面介紹虛擬dom
const frag = document.createDocumentFragment()
return frag;
複製代碼
寫正則 匹配 {{裏面的所有}}
const reg = /\{\{(.*)\}\}/;
複製代碼
來查找到DOM節點上有這個屬性的
if(node.nodeType === 3){
if(reg.test(node.nodeValue)){
let name = RegExp.$1;
name = name.trim();
new Watcher(vm, node, name, 'nodeValue');
}
}
複製代碼
尋找input
for(let i = 0; i < attributes.length; i++){
if(attributes[i].nodeName == 'v-model'){
const { nodeValue } = attributes[i];
node.addEventListener('input', function(e){
vm[nodeValue] = e.target.value;
})
new Watcher(vm, node, nodeValue, 'value');
}
}
複製代碼
export default function Warcher(vm, node, name, type) {
Dep.target = this;
this.name = name;
this.node = node;
this.vm = vm;
this.type = type;
this.update();
Dep.target = null;
}
複製代碼
Dep.target 大家發現了什麼
往下看
Warcher.prototype.update = function () {
this.get();
const batcher = new Batcher();
batcher.push(this)
};
Warcher.prototype.cb = function () {
this.node[this.type] = this.vm.text;
};
Warcher.prototype.get = function () {
this.node[this.type] = this.vm[this.name];
};
複製代碼
是否是丟失的都找到了呀
Dep.target
update()
那麼Dep是什麼鬼
export default function Dep(){
this.subs = [];
}
Dep.prototype.addSub = function (sub) {
this.subs.push(sub);
}
Dep.prototype.notify = function () {
this.subs.forEach((sub) => {
sub.update();
});
}
複製代碼
就是這麼說 把
export default function Dep(){
this.subs = [Dep.target,Dep.target,Dep.target];
}
複製代碼
Dep.prototype.notify = function () {
this.subs.forEach((sub) => {
sub.update(); ==== Dep.target.update();
});
}
複製代碼
這樣結合上面的雙向數據綁定解釋