全面解析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 相关文章推荐
Save a File Using a File Save Dialog Box
Jun 18 Javascript
js利用Array.splice实现Array的insert/remove
Jan 13 Javascript
深入Javascript函数、递归与闭包(执行环境、变量对象与作用域链)使用详解
May 08 Javascript
关于javascript event flow 的一个bug详解
Sep 17 Javascript
JS操作Cookies的小例子
Oct 15 Javascript
node爬取微博的数据的简单封装库nodeweibo使用指南
Jan 02 Javascript
Bootstrap学习系列之使用 Bootstrap Typeahead 组件实现百度下拉效果
Jul 07 Javascript
详解jQuery中关于Ajax的几个常用的函数
Jul 17 jQuery
Vue 路由切换时页面内容没有重新加载的解决方法
Sep 01 Javascript
微信小程序吸底区域适配iPhoneX的实现
Apr 09 Javascript
vue Element左侧无限级菜单实现
Jun 10 Javascript
利用JavaScript写一个简单计算器
Nov 27 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
收音机发烧友应当熟知的100条知识
2021/03/02 无线电
Oracle Faq(Oracle的版本)
2006/10/09 PHP
PHP操作mysql函数详解,mysql和php交互函数
2011/05/19 PHP
深入理解curl类,可用于模拟get,post和curl下载
2013/06/08 PHP
PHP怎么实现网站保存快捷方式方便用户随时浏览
2013/08/15 PHP
PHP上传图片、删除图片简单实例
2016/11/12 PHP
PHP后台微信支付和支付宝支付开发
2017/04/28 PHP
linux mint下安装phpstorm2020包括JDK部分的教程详解
2020/09/17 PHP
JS 对输入框进行限制(常用的都有)
2013/07/30 Javascript
js 模式窗口(模式对话框和非模式对话框)的使用介绍
2014/07/17 Javascript
AngularJS模块管理问题的非常规处理方法
2015/04/29 Javascript
javascript实现表单验证
2016/01/29 Javascript
angular route中使用resolve在uglify压缩后问题解决
2016/09/21 Javascript
纯JavaScript手写图片轮播代码
2016/10/20 Javascript
完美解决IE不支持Data.parse()的问题
2016/11/24 Javascript
jQuery实现的鼠标滚轮控制图片缩放功能实例
2017/10/14 jQuery
Express系列之multer上传的使用
2017/10/27 Javascript
html中通过JS获取JSON数据并加载的方法
2017/11/30 Javascript
js删除数组中的元素delete和splice的区别详解
2018/02/03 Javascript
在Python中使用成员运算符的示例
2015/05/13 Python
利用Python实现网络测试的脚本分享
2017/05/26 Python
Python爬取商家联系电话以及各种数据的方法
2018/11/10 Python
TensorFlow dataset.shuffle、batch、repeat的使用详解
2020/01/21 Python
Python单例模式的四种创建方式实例解析
2020/03/04 Python
Django框架models使用group by详解
2020/03/11 Python
python 实现分组求和与分组累加求和代码
2020/05/18 Python
解决Python安装cryptography报错问题
2020/09/03 Python
通过代码实例了解Python异常本质
2020/09/16 Python
一款纯css3实现的tab选项卡的实列教程
2014/12/11 HTML / CSS
Html5导航栏吸顶方案原理与对比实现
2020/06/10 HTML / CSS
新学期红领巾广播稿
2014/10/04 职场文书
房屋租赁合同补充协议
2014/10/11 职场文书
党员考试作弊检讨书1000字
2015/02/16 职场文书
简历上的自我评价,该怎么写呢?
2019/06/13 职场文书
java Nio使用NioSocket客户端与服务端交互实现方式
2021/06/15 Java/Android
python识别围棋定位棋盘位置
2021/07/26 Python