全面解析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实现图片翻页效果
Dec 23 Javascript
jQuery(js)获取文字宽度(显示长度)示例代码
Dec 31 Javascript
jquery实现删除一个元素后面的所有元素功能
Dec 21 Javascript
Backbone.js框架中简单的View视图编写学习笔记
Feb 14 Javascript
JS验证逗号隔开可以是中文字母数字
Apr 22 Javascript
JS加载iFrame出现空白问题的解决办法
May 13 Javascript
AngularJS中的表单简单入门
Jul 28 Javascript
详解Bootstrap各式各样的按钮(推荐)
Dec 13 Javascript
Vue 2.0+Vue-router构建一个简单的单页应用(附源码)
Mar 14 Javascript
js实现图片放大展示效果
Aug 30 Javascript
layui 根据后台数据动态创建下拉框并同时默认选中的实例
Sep 02 Javascript
js实现无缝轮播图
Mar 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解析url的三个示例
2014/01/20 PHP
PHP的PDO操作简单示例
2016/03/30 PHP
PHP数组操作简单案例分析
2016/10/15 PHP
推荐自用 Javascript 缩图函数 (onDOMLoaded)……
2007/10/23 Javascript
再谈javascript 动态添加样式规则 W3C校检
2009/12/25 Javascript
javascript setAttribute, getAttribute 在不同浏览器上的不同表现
2010/08/05 Javascript
jquery列表拖动排列(由项目提取相当好用)
2014/06/17 Javascript
javascript正则表达式中分组详解
2016/07/17 Javascript
Centos7 中 Node.js安装简单方法
2016/11/02 Javascript
详解获取jq ul第一个li定位的四种解决方案
2016/11/23 Javascript
JQuery实现图片轮播效果
2017/05/08 jQuery
解决vue打包项目后刷新404的问题
2018/03/06 Javascript
JavaScript递归函数解“汉诺塔”算法代码解析
2018/07/05 Javascript
微信小程序购物车、父子组件传值及calc的注意事项总结
2018/11/14 Javascript
Vuex持久化插件(vuex-persistedstate)解决刷新数据消失的问题
2019/04/16 Javascript
跟老齐学Python之开始真正编程
2014/09/12 Python
Python访问MySQL封装的常用类实例
2014/11/11 Python
Python实现获取网站PR及百度权重
2015/01/21 Python
Python中字典的setdefault()方法教程
2017/02/07 Python
Python实现查找匹配项作处理后再替换回去的方法
2017/06/10 Python
Django model 中设置联合约束和联合索引的方法
2019/08/06 Python
使用jupyter notebook将文件保存为Markdown,HTML等文件格式
2020/04/14 Python
django template实现定义临时变量,自定义赋值、自增实例
2020/07/12 Python
python用Configobj模块读取配置文件
2020/09/26 Python
Python Unittest原理及基本使用方法
2020/11/06 Python
HTML5中的新元素介绍
2008/10/17 HTML / CSS
HTML5给汉字加拼音收起展开组件的实现代码
2020/04/08 HTML / CSS
韩国邮政旗下生鲜食品网上超市:epost
2016/08/27 全球购物
老师对学生的评语
2014/04/18 职场文书
村班子对照检查材料
2014/08/18 职场文书
学生评语集锦
2015/01/04 职场文书
教师“一帮一”结对子活动总结
2015/05/07 职场文书
走近毛泽东观后感
2015/06/04 职场文书
导游词之吉林花园山
2019/10/17 职场文书
MySQL连接查询你真的学会了吗?
2021/06/02 MySQL
浅谈Redis中的RDB快照
2021/06/29 Redis