Skip to content

Commit

Permalink
mvvm
Browse files Browse the repository at this point in the history
  • Loading branch information
wuyw committed Apr 9, 2019
1 parent dee4803 commit 1df15b0
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 52 deletions.
17 changes: 16 additions & 1 deletion vue/mvvm/1.md
Original file line number Diff line number Diff line change
Expand Up @@ -637,4 +637,19 @@ new Watcher(data, 'age', print2);
data.age = '24'; // 我今年 24
```
## MVVM
### 概念
说了那么多,该练练手了。Vue 作为典型的 MVVM 框架,大大提高了前端er 的生产力,我们这次就参考 Vue 自己实现一个简易的 MVVM。
### 什么是 MVVM ?
简单介绍一下 MVVM,更全面的讲解,大家可以看这里 [MVVM 模式](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/hh848246(v=pandp.10))。MVVM 的全称是 Model-View-ViewModel,它是一种架构模式,最早由微软提出,借鉴了 MVC 等模式的思想。
ViewModel 负责把 Model 的数据同步到 View 显示出来,还负责把 View 对数据的修改同步回 Model。而 Model 层作为数据层,它只关心数据本身,不关心数据如何操作和展示;View 是视图层,负责将数据模型转化为 UI 界面展现给用户。
![](https://user-gold-cdn.xitu.io/2019/4/9/169ffa330a643c73?w=406&h=279&f=png&s=20155)
> 图片来自 [MVVM 模式](https://docs.microsoft.com/en-us/previous-versions/msp-n-p/hh848246(v=pandp.10))
### 如何实现一个 MVVM?
想知道如何实现一个 MVVM,至少我们得先知道 MVVM 有什么。Vue 的响应式原理图,其实就已经可以基本说明问题了。但是为了方便理解,我们还是大致画一下原理图。
![](https://user-gold-cdn.xitu.io/2019/4/9/16a001f32f9e505c?w=700&h=481&f=jpeg&s=101106)
从图中看,我们现在需要做哪些事情呢?数据劫持、数据代理、模板编译、发布订阅,等一下,这些名词是不是看起来很熟悉?这不就是之前分析 Vue 源码时候做的事吗?(是啊,是啊,可不就是抄的 Vue 嘛)。OK,数据劫持、发布订阅我们都比较熟悉了,可是模板编译还没有头绪。不急,这就开始。
3 changes: 0 additions & 3 deletions vue/mvvm/Compile.js

This file was deleted.

46 changes: 1 addition & 45 deletions vue/mvvm/MVVM.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,2 @@
/**
* Created by wyw on 2019/3/10.
*/
// 在需要订阅的地方(如:模版编译),添加观察者(watcher),并立刻通过取值触发指定属性的get方法,从而将观察者添加进订阅系统Dep,然后在 Set 的时候,进行 notify,通知给所有观察者进行响应的update
class Dep{
constructor() {
this.subs = [];
}
addSub(sub) {
this.subs.push(sub);
}
notify() {
console.log(this.subs);
}
}
function observer(data, key, val) {
let dep = new Dep();
Object.defineProperty(data, key, {
get() {
Dep.target && dep.addSub(Dep.target);
return val;
},
set(newval) {
val = newval;
dep.notify();
}
})
}

let obj = {name: 'a', age: 18, sex: 'man'};
Object.keys(obj).forEach(k => {
observer(obj, k, obj[k]);
});

Dep.target = 1;
console.log(obj.name);
Dep.target = null;

Dep.target = 2;
console.log(obj.age);
Dep.target = null;

obj.name = 'b';
obj.age = 32;
obj.name = 'cccccc';
console.log(obj.name, obj.age);
}
43 changes: 43 additions & 0 deletions vue/mvvm/Observer.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,46 @@
/**
* Created by wyw on 2019/3/10.
*/
// 在需要订阅的地方(如:模版编译),添加观察者(watcher),并立刻通过取值触发指定属性的get方法,从而将观察者添加进订阅系统Dep,然后在 Set 的时候,进行 notify,通知给所有观察者进行响应的update
class Dep{
constructor() {
this.subs = [];
}
addSub(sub) {
this.subs.push(sub);
}
notify() {
console.log(this.subs);
}
}
function observer(data, key, val) {
let dep = new Dep();
Object.defineProperty(data, key, {
get() {
Dep.target && dep.addSub(Dep.target);
return val;
},
set(newval) {
val = newval;
dep.notify();
}
})
}

let obj = {name: 'a', age: 18, sex: 'man'};
Object.keys(obj).forEach(k => {
observer(obj, k, obj[k]);
});

Dep.target = 1;
console.log(obj.name);
Dep.target = null;

Dep.target = 2;
console.log(obj.age);
Dep.target = null;

obj.name = 'b';
obj.age = 32;
obj.name = 'cccccc';
console.log(obj.name, obj.age);
3 changes: 0 additions & 3 deletions vue/mvvm/Watcher.js

This file was deleted.

0 comments on commit 1df15b0

Please sign in to comment.