全面解析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 相关文章推荐
functional继承模式 摘自javascript:the good parts
Jun 20 Javascript
终于解决了IE8不支持数组的indexOf方法
Apr 03 Javascript
让复选框只能选择一项的方法
Oct 08 Javascript
Javascript检查图片大小不要让大图片撑破页面
Nov 04 Javascript
基于jQuery实现的文字按钮表单特效整理
Dec 07 Javascript
js代码验证手机号码和电话号码是否合法
Jul 30 Javascript
js实现可折叠展开的手风琴菜单效果
Sep 07 Javascript
js实现的鼠标滚轮滚动切换页面效果(类似360默认页面滚动切换效果)
Jan 27 Javascript
浅谈React中组件间抽象
Jan 27 Javascript
d3.js实现自定义多y轴折线图的示例代码
May 30 Javascript
vue+iview/elementUi实现城市多选
Mar 28 Javascript
vue使用websocket的方法实例分析
Jun 22 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中对缓冲区的控制实现代码
2013/09/29 PHP
如何在旧的PHP系统中使用PHP 5.3之后的库
2015/12/02 PHP
jQuery JSON实现无刷新三级联动实例探讨
2013/05/28 Javascript
JS Map 和 List 的简单实现代码
2013/07/08 Javascript
JavaScript两种跨域技术全面介绍
2014/04/16 Javascript
Js操作树节点自动折叠展开的几种方法
2014/05/05 Javascript
JS定义类的六种方式详解
2016/05/12 Javascript
基于Angularjs实现分页功能
2016/05/30 Javascript
jQuery图片左右滚动代码 有左右按钮实例
2016/06/20 Javascript
node.js版本管理工具n无效的原理和解决方法
2016/11/24 Javascript
vue2.0与bootstrap3实现列表分页效果
2017/11/28 Javascript
解决Vue2.x父组件与子组件之间的双向绑定问题
2018/03/06 Javascript
关于Angularjs中自定义指令一些有价值的细节和技巧小结
2018/04/22 Javascript
AngularJS模态框模板ngDialog的使用详解
2018/05/11 Javascript
nodejs通过钉钉群机器人推送消息的实现代码
2019/05/05 NodeJs
微信小程序本地存储实现每日签到、连续签到功能
2019/10/09 Javascript
[41:08]2014 DOTA2国际邀请赛中国区预选赛 HGT VS NE
2014/05/22 DOTA
flask中主动抛出异常及统一异常处理代码示例
2018/01/18 Python
pyqt5实现俄罗斯方块游戏
2019/01/11 Python
python实现Excel文件转换为TXT文件
2019/04/28 Python
django做form表单的数据验证过程详解
2019/07/26 Python
在Pytorch中使用样本权重(sample_weight)的正确方法
2019/08/17 Python
python opencv图片编码为h264文件的实例
2019/12/12 Python
Pytorch训练过程出现nan的解决方式
2020/01/02 Python
Python Numpy,mask图像的生成详解
2020/02/19 Python
Dr. Martens马汀博士法国官网:马丁靴鼻祖
2020/01/15 全球购物
Linux管理员面试题 Linux admin interview questions
2016/07/08 面试题
数控专业应届生求职信
2013/11/27 职场文书
微观物理专业自荐信
2014/01/26 职场文书
创先争优活动方案
2014/02/12 职场文书
大学生优秀班干部事迹材料
2014/05/26 职场文书
敬老月活动总结
2014/08/28 职场文书
党委书记群众路线对照检查材料思想汇报
2014/10/04 职场文书
工作检讨书怎么写
2014/10/10 职场文书
迎新年主持词
2015/07/06 职场文书
纯html+css实现打字效果
2021/08/02 HTML / CSS