全面解析vue中的数据双向绑定


Posted in Javascript onMay 10, 2017

1.vue中数据的双向绑定采用的时候,数据劫持的模式。其实主要是用了Es5中的Object.defineProperty;来劫持每个属性的getter,和setter。这也正是Vue不兼容IE8以下的原因。

2.Object.defineProerty();

var obj = {};
    Object.defineProperty(obj,"hello",{
      enumerable: true,   //表示这个属性能够通过 for -- in 循环 (是否可枚举);
      configurable: true,  //表示这个属性能否用 delete 删除
      get(){ //获取属性值,说白了就是返回值
        return this.val;
      },
      set(newVale){ //对属性的处理 (说白了: 就是在赋值的过程中提供一个方法来决定返回值)
        this.val = newVale + 5; 
        console.log(this.val); // 10
      }
    })
    obj.hello = 5;
    console.log(obj.hello) ; // 10

3.实现简单的双向绑定

<input type="text" id="a">
<div id="b"></div>
<script type="text/javascript">
  var obj = {};
  Object.defineProperty(obj,`value`,{
    enumerable: true,
    configurable: true,
    get(){
      return this.val;
    },
    set(newValue){
      document.getElementById(`b`).innerText = newValue;
      this.val = newValue; //66
    }
  });
  document.getElementById(`a`).addEventListener(`input`,function(event){
    var text = event.target.value; //66
    obj.value = text;
  },false)
</script>

这种方式简单粗暴,直接通过操作DOM完成绑定。我想,肯定有人会认为,你这样写,还不如在input事件中直接对Id为B的DOM元素赋值,这样不是多此一举吗?请看下面在框架中我们该如何实现。

4.实现简单的  v-model

首先我们需要获取文档中的真实元素节点也就是VUE中实列话VUE中元素挂载点(el);在通过createDocumentFragment创建文档碎片,解析操作完毕后,把碎片放置在DOM中。

<div id="app">
  <input type="text" id="a" v-model="text">
  {{text}}
</div>
 <script type="text/javascript">
  function Model(node, vm) {
    if(node) {this.$frag = this.nodeToFragment(node, vm);
      return this.$frag;
    }
  }
  Model.prototype = {
    construtor:'Model',
    nodeToFragment: function(node, vm) {
      var self = this;
      var frag = document.createDocumentFragment();
      var child;
      while(child = node.firstChild) {
        self.moelElement(child, vm);
        frag.appendChild(child); 
// 将所有子节点添加到fragment中,child是指向元素首个子节点的引用。
// 将child引用指向的对象append到父对象的末尾,原来child引用的对象就跳到了frag对象的末尾,
// 而child就指向了本来是排在第二个的元素对象。如此循环下去,链接就逐个往后跳了
      }
      return frag;
    },
    moelElement: function(node, vm) {
      var reg = /\{\{(.*)\}\}/; //匹配 {{}} () 获取匹配到的值
      //节点类型为元素
      if(node.nodeType === 1) {
        var attr = node.attributes;
        // 解析属性
        for(var i = 0; i < attr.length; i++ ) {
          if(attr[i].nodeName == 'v-model') {
            var name = attr[i].nodeValue; // 获取v-model绑定的属性名
            node.addEventListener('input', function(e) {
              // 给相应的data属性赋值,进而触发该属性的set方法
              vm.data[name]= e.target.value;
            });
            node.value = vm.data[name]; // 将data的值赋给该node
            node.removeAttribute('v-model');
          }
        };
      }
      //节点类型为text
      if(node.nodeType === 3) {
        if(reg.test(node.nodeValue)) {
          var name = RegExp.$1; // 获取匹配到的字符串 () 正则中的分组。通过$1获取第一个分组
          name = name.trim();
          node.nodeValue = vm.data[name]; // 将data的值赋给该node
        }
      }
    },
  }
  function Vue(options) {
    this.data = options.data;
    var data = this.data;
    var id = options.el;
    var dom =new Model(document.getElementById(id),this);
    // 编译完成后,将dom返回到app中
    document.getElementById(id).appendChild(dom);
  }
  var vm = new Vue({
    el: 'app',
    data: {
      text: 'hello world'
    }
  });
</script>

到这里主要是学习了VUE中对指令的处理。到这儿你就可以添加只自定义的指令了。同时也明白自定义指令是如何实现的了。当然数据的双向绑定是还没有实现的。

以上所述是小编给大家介绍的vue中的数据双向绑定,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
JavaScript 常见对象类创建代码与优缺点分析
Dec 07 Javascript
js replace替换所有匹配的字符串
Feb 13 Javascript
jquery获取radio值实例
Oct 16 Javascript
JavaScript控制table某列不显示的方法
Mar 16 Javascript
jquery分割字符串的方法
Jun 24 Javascript
jQuery遍历节点树方法分析
Sep 08 Javascript
Bootstrap基本插件学习笔记之折叠(22)
Dec 08 Javascript
JS实现太极旋转思路分析
Dec 09 Javascript
JS作用域深度解析
Dec 29 Javascript
JavaScript中transform实现数字翻页效果
Mar 08 Javascript
layui 上传图片 返回图片地址的方法
Sep 26 Javascript
原生js实现自定义滚动条组件
Jan 20 Javascript
利用forever和pm2部署node.js项目过程
May 10 #Javascript
javascript简单链式调用案例分析
May 10 #Javascript
Angular.JS通过指令操作DOM的方法
May 10 #Javascript
JS实现队列的先进先出功能示例
May 10 #Javascript
BootStrap的两种模态框方式
May 10 #Javascript
微信小程序之购物车功能
Sep 23 #Javascript
js canvas实现QQ拨打电话特效
May 10 #Javascript
You might like
php 遍历数据表数据并列表横向排列的代码
2009/09/05 PHP
Php连接及读取和写入mysql数据库的常用代码
2014/08/11 PHP
php创建桌面快捷方式实现方法
2015/12/31 PHP
php微信开发之上传临时素材
2016/06/24 PHP
thinkphp实现把数据库中的列的值存到下拉框中的方法
2017/01/20 PHP
PHP并发场景的三种解决方案代码实例
2021/02/27 PHP
js滚动条多种样式,推荐
2007/02/05 Javascript
js的with语句使用方法
2007/09/21 Javascript
JS文本框追加多个下拉框的值的简单实例
2013/07/12 Javascript
jQuery获取当前对象标签名称的方法
2014/02/07 Javascript
js的参数有长度限制吗?发现不能超过2083个字符
2014/04/20 Javascript
js动态控制table的tr、td增加及删除的具体实现
2014/04/30 Javascript
JavaScript采用递归算法计算阶乘实例
2015/08/04 Javascript
浅析AngularJs HTTP响应拦截器
2015/12/28 Javascript
javascript类型系统——undefined和null全面了解
2016/07/13 Javascript
浅析JavaScript中的array数组类型系统
2016/07/18 Javascript
浅析JavaScript函数的调用模式
2016/08/10 Javascript
JS实现拖动滚动条评分的效果代码分享
2016/09/29 Javascript
jquery 追加元素append、prepend、before、after用法与区别分析
2016/12/02 Javascript
jquery pagination分页插件使用详解(后台struts2)
2017/01/22 Javascript
使用Python3编写抓取网页和只抓网页图片的脚本
2015/08/20 Python
Python实现二维有序数组查找的方法
2016/04/27 Python
Python用csv写入文件_消除空余行的方法
2018/07/06 Python
用python实现一个简单的验证码
2020/12/09 Python
一级方程式赛车官方网上商店:F1 Store(支持中文)
2018/01/12 全球购物
佳能加拿大网上商店:Canon eStore Canada
2018/04/04 全球购物
单身旅行者的单身假期:Just You
2018/04/08 全球购物
PPP协议组成及简述协议协商的基本过程
2015/05/28 面试题
Does C# support multiple inheritance? (C#支持多重继承吗)
2012/01/04 面试题
Windows和Linux动态库应用异同
2016/07/28 面试题
学院书画协会部门岗位职责
2013/12/01 职场文书
大学生职业生涯规划范文
2013/12/31 职场文书
2014年法院个人工作总结
2014/12/17 职场文书
综合素质自我评价评语
2015/03/06 职场文书
运动会表扬稿范文
2015/05/05 职场文书
起诉状范本
2015/05/20 职场文书