已解决1600个留学问题,快来看看吧!

技术帮:利用 JavaScript 数据绑定实现一个简单的 MVVM 库

MVVM 是 Web 前端一种非常流行的开发模式,利用 MVVM 可以使我们的代码更专注于处理业务逻辑而不是去关心 DOM 操作。目前著名的 MVVM 框架有 vue, avalon , angular 等,这些框架各有千秋,但是实现的思想大致上是相同的:数据绑定 + 视图刷新。出于好奇和一颗愿意折腾的心,我自己也沿着这个方向写了一个最简单的 MVVM 库 ( mvvm.js ),总共 2000 多行代码,指令的命名和用法与 vue 相似,在这里分享一下实现的原理以及我的代码组织思路。

思路整理

MVVM 在概念上是真正将视图与数据逻辑分离的模式,ViewModel 是整个模式的重点。要实现 ViewModel 就需要将数据模型(Model)和视图(View)关联起来,整个实现思路可以简单的总结成 5 点:

  1. 实现一个 Compiler 对元素的每个节点进行指令的扫描和提取;

  2. 实现一个 Parser 去解析元素上的指令,能够把指令的意图通过某个刷新函数更新到 dom 上(中间可能需要一个专门负责视图刷新的模块)比如解析节点 <p v-show="isShow"></p> 时先取得 Model 中 isShow 的值,再根据 isShow 更改 node.style.display 从而控制元素的显示和隐藏;

  3. 实现一个 Watcher 能将 Parser 中每条指令的刷新函数和对应 Model 的字段联系起来;

  4. 实现一个 Observer 使得能够对对象的所有字段进行值的变化监测,一旦发生变化时可以拿到最新的值并触发通知回调;

  5. 利用 Observer 在 Watcher 中建立一个对 Model 的监听 ,当 Model 中的一个值发生变化时,监听被触发,Watcher 拿到新值后调用在步骤 2 中关联的那个刷新函数,就可以实现数据变化的同时刷新视图的目的。

效果示例

首先粗看下最终的使用示例,与其他 MVVM 框架的实例化大同小异:

<div id="mobile-list"> <h1 v-text="title"></h1> <ul> <li v-for="item in brands"> <b v-text="item.name"></b> <span v-show="showRank">Rank: {{item.rank}}</span> </li> </ul> </div>
var element = document.querySelector('#mobile-list'); var vm = new MVVM(element, { 'title' : 'Mobile List', 'showRank': true, 'brands' : [
        {'name': 'Apple', 'rank': 1},
        {'name': 'Galaxy', 'rank': 2},
        {'name': 'OPPO', 'rank': 3}
    ]
});

vm.set('title', 'Top 3 Mobile Rank List'); // => <h1>Top 3 Mobile Rank List</h1>

最后编辑于:2016-11-29 03:38:48
  • 自己顶

    最后编辑于:2016-11-29 03:45:01
发表回复