全面解析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 textarea光标定位方法(兼容IE和FF)
Mar 12 Javascript
javascript实现json页面分页实例代码
Feb 20 Javascript
浅谈javascript中call()、apply()、bind()的用法
Apr 20 Javascript
jQuery实现的淡入淡出二级菜单效果代码
Sep 15 Javascript
JavaScript中解决多浏览器兼容性23个问题的快速解决方法
May 19 Javascript
Javascript小技能总结(推荐)
Jun 02 Javascript
自己封装的一个简单的倒计时功能实例
Nov 23 Javascript
解决Vue在封装了Axios后手动刷新页面拦截器无效的问题
Nov 08 Javascript
layui实现三级联动效果
Jul 26 Javascript
javascript面向对象程序设计实践常用知识点总结
Jul 29 Javascript
小程序登录之支付宝授权的实现示例
Dec 13 Javascript
五句话帮你轻松搞定js原型链
Dec 09 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添加MySQL数据记录代码
2008/06/07 PHP
php中解析带中文字符的url函数分享
2015/01/20 PHP
php使用GD创建保持宽高比缩略图的方法
2015/04/17 PHP
PHP中include()与require()的区别说明
2017/02/14 PHP
js 针对html DOM元素操作等经验累积
2014/03/11 Javascript
在jquery中的ajax方法怎样通过JSONP进行远程调用
2014/04/04 Javascript
2014 HTML5/CSS3热门动画特效TOP10
2014/12/07 Javascript
HTML5使用DeviceOrientation实现摇一摇功能
2015/06/05 Javascript
Javascript 高阶函数使用介绍
2015/06/15 Javascript
JS遍历页面所有对象属性及实现方法
2016/08/01 Javascript
jquery设置css样式的多种方法(总结)
2017/02/21 Javascript
浅谈JavaScript作用域和闭包
2017/09/18 Javascript
浅谈node中的cluster集群
2018/06/02 Javascript
微信小程序开发之自定义tabBar的实现
2018/09/06 Javascript
vue+elementUi图片上传组件使用详解
2019/08/20 Javascript
node.js基础知识汇总
2020/08/25 Javascript
多种类型jQuery网页验证码插件代码实例
2021/01/09 jQuery
用Python的SimPy库简化复杂的编程模型的介绍
2015/04/13 Python
python os.path模块常用方法实例详解
2018/09/16 Python
python hook监听事件详解
2018/10/25 Python
Python实现简单查找最长子串功能示例
2019/02/26 Python
用Python实现校园通知更新提醒功能
2019/11/23 Python
python列表生成器迭代器实例解析
2019/12/19 Python
基于nexus3配置Python仓库过程详解
2020/06/15 Python
洛佩桑酒店官方网站:Lopesan Hotels
2019/04/15 全球购物
网络维护管理员的自我评价分享
2013/11/11 职场文书
奥巴马竞选演讲稿
2014/05/15 职场文书
企业优秀团员事迹材料
2014/08/20 职场文书
青春励志演讲稿范文
2014/08/25 职场文书
清洁工岗位职责
2015/02/13 职场文书
合作与交流自我评价
2015/03/09 职场文书
求职信范文怎么写
2015/03/19 职场文书
2015年社区科普工作总结
2015/05/13 职场文书
个人催款函范文
2015/06/23 职场文书
Python爬虫实战之爬取京东商品数据并实实现数据可视化
2021/06/07 Python
Python Matplotlib绘制两个Y轴图像
2022/04/13 Python