我个人以为mvvm框架里面最重要的一点就是VM这部分,它要与Model层建立联系,将Model层转换成可以被View层识别的数据结构;其次也要同View建立联系,将数据及时更新到View层上,并且响应View对数据的更改,同步到Model层。

MVVM的具体例子,可以看一下阮一峰老师的这篇博客

我们提取其中比较关键的点:

  1. Model层存储数据
  2. 需要一个View-Model来对数据做中转,响应数据变化,同步到两端
  3. View层来负责展示数据,接受用户事件

Model层,我们用一个对象来代表。例如:

let data = {
text: 'foo'
};

View层对于我们而言,可以认为是DOM节点。例如:

<div id="app">
<p>text</p>
</div>

为了方便注入内容,改用JS来写,可以写成

let str = `<div id="app"><p>test</p></div>`;

至于View-Model,我们要做两件事,一是将数据及时同步到View层,二是响应用户事件,更改数据。我们设计一个函数来完成这项工作。

// 把对象转成可监听的
const ob = function (data) {
// 无new构造
if (!(this instanceof ob)) {
return new ob(data);
}
// 设定观察者列表
let observerList = []; // 暴露添加观察者方法
this.addOb = function (fn) {
observerList.push(fn);
} // 遍历属性,通过defineProperty来对属性变化做监听
for (let key in data) {
let value = data[key];
Object.defineProperty(data, key, {
enumerable:true, // 枚举
get () {
return value;
},
set (newVal) {
value = newVal;
observerList.forEach((el)=>{
el(newVal);
})
}
})
}
};

为了简单起见,把View的渲染封装成一个函数,当然实际上不能这么操作。

const render = (text) => {
document.getElementById('app').innerHTML = '<p>'+ text +'</p>';
}

然后将render和数据绑定起来。

let testObj = {
name: 'liu'
}; const vm = (data) => {
render(testObj.name);
let newOb = ob(data);
newOb.addOb(function () {
render(data.name);
})
}; vm(testObj); // 如果直接设置testObj.name = 'test';就会触发对应的修改

以上,基本上实现了数据和视图间的绑定。

可以再继续改进,在render之前,加入virtual dom的逻辑,或者加入一些语法特性,比如类似VUE和React的语法糖。

由于直接设置对象属性其实不大安全,而且不易于追踪,可以把状态统一提取出来,进一步封装,只能通过action去触发修改,然后分发到各个调用方。保证数据的单项流动。

这里是一个简单的例子

感谢阅读。

最新文章

  1. Python 基本语法 学习之路(三)
  2. Web API应用架构在Winform混合框架中的应用(3)--Winfrom界面调用WebAPI的过程分解
  3. PetaPoco入门(二)
  4. iOS开发网络篇—HTTP协议
  5. Logistic回归原理及公式推导[转]
  6. 【转】有趣的Autolayout示例-Masonry实现
  7. C/C++:类模板
  8. GridControl 复合表头(多行标题)
  9. MSSQL批量替换网址字符串语句
  10. delphi 句柄
  11. 201521123101 《Java程序设计》第11周学习总结
  12. Linux入门之常用命令(5)Bash
  13. Unicode vs. UTF-8 etc.
  14. python pytz时区设置模块
  15. SQL Server 增、删、改、小部分查
  16. ggplot2 pdf import in Adobe Illustrator missing font AdobePiStd
  17. 半夜思考, Java 重载的实现
  18. Syncthing源码解析 - 在Gogland中对Syncthing的各个模块进行调试?
  19. [翻译] ASCScreenBrightnessDetector
  20. Django【进阶】分页功能Pagination

热门文章

  1. vc++返回模块路径
  2. python对excel文件的读写操作
  3. web前端css实现六边形效果
  4. 排序算法Nb三人组-快速排序
  5. 动态赋值poster,无法显示
  6. 【windows c】 遍历目录
  7. csdn中使用Git的一些注意问题
  8. python csv写入数据,消除空行
  9. C# 时间格式(血淋淋的教训啊。。。)
  10. unity3d中设计模式的学习&lt;一&gt;:泛型单例