全面解析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 相关文章推荐
JQUERY设置IFRAME的SRC值的代码
Nov 30 Javascript
javascript中[]和{}对象使用介绍
Mar 20 Javascript
JavaScript执行顺序详细介绍
Dec 04 Javascript
javascript不同类型数据之间的运算的转换方法
Feb 13 Javascript
原生javascript实现拖动元素示例代码
Sep 01 Javascript
javascript框架设计读书笔记之字符串的扩展和修复
Dec 02 Javascript
浅谈jquery点击label触发2次的问题
Jun 12 Javascript
jQuery生成假加载动画效果
Dec 01 Javascript
vue框架搭建之axios使用教程
Jul 11 Javascript
利用d3.js力导布局绘制资源拓扑图实例教程
Jan 08 Javascript
Vue入门学习笔记【基本概念、对象、过滤器、指令等】
Apr 13 Javascript
json_decode 索引为数字时自动排序问题解决方法
Mar 28 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中file_exists函数不支持中文名的解决方法
2014/07/26 PHP
PHP读取CURL模拟登录时生成Cookie文件的方法
2014/11/04 PHP
PHP实现支付宝即时到账功能
2016/12/21 PHP
PHP数据库处理封装类实例
2016/12/24 PHP
PHP全功能无变形图片裁剪操作类与用法示例
2017/01/10 PHP
小议Function.apply() 之一------(函数的劫持与对象的复制)
2006/11/30 Javascript
类似CSDN图片切换效果脚本
2009/09/17 Javascript
jQuery文件上传插件Uploadify使用指南
2014/06/05 Javascript
node.js中的http.response.setHeader方法使用说明
2014/12/14 Javascript
Angularjs中使用轮播图指令swiper
2017/05/30 Javascript
vue实现简单loading进度条
2018/06/06 Javascript
vue多层嵌套路由实例分析
2019/03/19 Javascript
jquery+php后台实现省市区联动功能示例
2019/05/23 jQuery
详解JavaScript的this指向和绑定
2020/09/08 Javascript
[05:06]DOTA2-DPC中国联赛 正赛 VG vs Magma选手采访
2021/03/11 DOTA
Python Sql数据库增删改查操作简单封装
2016/04/18 Python
Python利用matplotlib生成图片背景及图例透明的效果
2017/04/27 Python
全面分析Python的优点和缺点
2018/02/07 Python
基于PyQt4和PySide实现输入对话框效果
2019/02/27 Python
pyqt5让图片自适应QLabel大小上以及移除已显示的图片方法
2019/06/21 Python
Pytorch之扩充tensor的操作
2021/03/04 Python
现代家居用品及礼品:LBC Modern
2018/06/24 全球购物
印度民族服装购物网站:BIBA
2019/08/05 全球购物
俄罗斯童装网上商店:BebaKids
2020/06/06 全球购物
给海归自荐信的建议
2013/12/13 职场文书
活动邀请函范文
2014/01/19 职场文书
会计专业毕业自荐书范文
2014/02/08 职场文书
《长城》教学反思
2014/02/14 职场文书
梅花魂教学反思
2014/04/25 职场文书
电视节目策划方案
2014/05/16 职场文书
节约用电标语
2014/06/17 职场文书
房产公证书
2015/01/23 职场文书
员工自我工作评价
2015/03/06 职场文书
旅游投诉信范文
2015/07/02 职场文书
PL350与SW11的比较
2021/04/22 无线电
Pytest中skip skipif跳过用例详解
2021/06/30 Python