美文网首页
动手实现数据双向绑定(1)

动手实现数据双向绑定(1)

作者: 忧郁的河蟹 | 来源:发表于2015-12-30 13:27 被阅读2371次

    前言

    自从Angular火了一把以后,数据与视图的双向绑定,已经成为了现代前端框架的标配,本系列将会探讨目前主流前端框架的双向绑定实现原理与代码实现。
    目前,对于双向绑定的实现,主要分为三个流派,Angular使用的是脏刷新,Vue使用的是Getter/Setter,而React 则是在脏刷新的的基础上,增加了虚拟dom树与实际dom树改变的刷新机制。

    基本原理

    遍历Dom树,解析Dom树上的字符串,当找到可以替换成model变量的字符串,替换成model的数据,同时,检测model的数据变化,数据变化的时候,触发渲染动作,对Dom进行重新渲染。对于Angular 与 Vue 主要的区别在数据变动检测部分。Vue利用object的getter/setter方法作为渲染的钩子产生渲染事件,而Angular则主动调用$digest激活数据脏刷新,React在脏刷新的基础上,放弃对Dom进行比较操作,直接从内存中比较出变化后,一次性生成到对应的Dom结构上。

    实现目标

    围绕上述三个双向绑定模式,我们将会用相同的案例来展现双向绑定的效果。

    html

    <div id="demo1" class="section">
      Hello <span class='{{css}}'>{{name}}</span>!
    </div>
    
    <div id='demo2' class='section'>
      <label><span>name:</span>
        <input name='name'>
      </label>
      <br>
      <label><span>password:</span>
        <input name='password'>
      </label>
      <pre>{
      name: {{name}},
      passowrd: {{password}}
    }</pre>
    </div>
    
    

    javascript

    var demo1 = mvvc('#demo1', {
      model: {
        name: 'world',
        css: 'green'    
      }
    });
    
    var demo2 = mvvm('#demo2', {
      type: 'form', // 同步
      model: {
        name: '',
        password: ''
      }
    })
    

    准备工作

    在分享各个双向数据绑定框架,抽取相同的逻辑部分进行分析。

    1.遍历Dom元素,提取属性与文本

    function renderDom(dom, model) {
      each(dom.attributes, function() {
        render(this, model);
      });
      
      each(dom.childNodes, function () {
        if (this.nodeType === 1) {
          return renderDom(this, model);
         }
        
        render(this, model);
      })
    }
    

    2.提取元素里面被提取的可变量{{name}}{{css}},并替换成model的变量后重新渲染页面。

    function render(node, model) {
      var self = this;
      var attr = node.textContent.split(start);
      if (!attr.length) return;
      var ret = '';
      for (var i = 0; i < attr.length; i++) {
        var two = attr[i].split(end);
        if (two.length == 1) {
          ret += attr[i];
        } else {
          ret = model[two[0] + two[1]];
        } 
        node.textContent = ret;
      }
    }
    

    3.成功实现model的数据渲染

    效果图
    代码参考:
    http://codepen.io/youyudehexie/pen/MKbXvM

    相关文章

      网友评论

          本文标题:动手实现数据双向绑定(1)

          本文链接:https://www.haomeiwen.com/subject/tyyihttx.html