模仿Vue写一个mvvm

网络上有不少教你如何模仿vue手写mvvm的视频,我历来没有本身动手写过。这周末想着必定要把这件事情完成。html

下面就关于vue如何实现two-way data-binding作一个简单的步骤梳理,文字有点多,不过逐步看下去或许会对你们有所启发哦,同时我也会把须要用到的知识点罗列出来~ vue

所谓双向绑定,即数据变化 -> 视图更新;视图交互变化(如input) -> 数据model变动的效果。node

演示地址react

何为mvvm?简言之,把数据和视图进行关联的一种模式。这四个字母能够这么理解: Model, View, ViewModel。git

模仿vue来写一个本身的mvvm,往简单来说,通常涉及下面三个步骤:github

  1. compile -- 模板编译
  2. observe -- 数据劫持
  3. watcher -- 监听model的变化,并告知视图从新编译,是链接compile和observe的桥梁

模板编译 Compile数组

  1. 用过vue的人都知道,html中有各类v-开头的指令,也有相似mustache的模板。这部份内容都是要用自定义的data数据进行绑定的。
    所以,模板的编译就是把你自定义的不管是v-(仍是k-,你随意~)开头的指令,仍是mustache,用你想要的data去替换。这是编译模板最开始须要想到的。
  2. 如何进行编译,咱们都知道频繁的操做dom是致使性能低下的一大缘由,相对于拼接字符串没法操做dom节点来说,把dom放到内存中操做能够大大提高速度,这就涉及document.createDocumentFragment方法。
    另外,还会要用到诸如appendChild, childNodes, node.attributes, node.textContent, node.nodeType, firstChild等原生js操做dom的方法。
    因为处理的dom集合都是类数组,因此一个频繁涉及到的原生js方法是Array.from,把类数组转化成数组;还有一个高频方法的是Array.prototype.reduce。
    还须要特别掌握的是,递归在项目中的运用。
    在具体处理的代码中就会考察你的基础知识啦。因此,光会用vue、react、angular啥的不行哦,就像你光知道这个机器怎么使用,一旦停电了或机器故障了,你就只能两手一摊了。
  3. 在内存中处理好以后,再把fragment放回到页面中便可。至此,页面最初始的模板编译完成。

数据劫持 Observe网络

所谓数据劫持就是当数据(必定是对象,引用类型的值)发生改变的时候,添加咱们本身的逻辑。通常状况下,咱们给对象赋值都是直接let obj = value,完毕。在这个过程当中咱们没法添加本身的逻辑,好比你但愿当对象的值发生改变时(即监听对象的变化,当发生改变时调用方法),例如给一个console输出或作点别的,却没法作到。app

那么如何添加本身的逻辑呢?答案就是ES5的Object.defineProperty方法。在调用Object.defineProperty方法时,若是不指定,configurable,enumerable和writable特性的默认值都是false,因此务必要把configurable和enumerable的值设置成true。最关键的是,给对像的某个key写上get和set方法,这样一来你就能够在取值和赋值的过程当中添加本身的逻辑了。dom

监听(数据)变化 Watcher

这是难点,也是关键点。

在Observe观察到对象数据发生变化了,可是没法改变视图(view)。因此,watcher的做用,就是给各个绑定数据的地方,一一对应的进行监听。在Observe发现数据变化后,调用watcher函数对相应的视图进行数据更新。

未完待续~

ps.我的认为单个功能的代码不超过30行比较好。若是超过了,能够拆分红多个细小的代码块,方便阅读,也方便梳理逻辑。

相关文章
相关标签/搜索