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();
});
}
复制代码
这样结合上面的双向数据绑定解释