全面解析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的一些特性和用法整理小结
Jan 13 Javascript
Extjs改变树节点的勾选状态点击按钮将复选框去掉
Nov 14 Javascript
利用jQuery简单实现产品展示图片左右滚动功能(示例代码)
Jan 02 Javascript
对比分析AngularJS中的$http.post与jQuery.post的区别
Feb 27 Javascript
javascript模拟评分控件实现方法
May 13 Javascript
javascript创建cookie、读取cookie
Mar 31 Javascript
jQuery对checkbox 复选框的全选全不选反选的操作
Aug 09 Javascript
扩展Bootstrap Tooltip插件使其可交互的方法
Nov 07 Javascript
canvas时钟效果
Feb 16 Javascript
angular中实现li或者某个元素点击变色的两种方法
Jul 27 Javascript
深入理解Vue nextTick 机制
Apr 28 Javascript
jQuery中each和js中forEach的区别分析
Feb 27 jQuery
利用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
第十四节--命名空间
2006/11/16 PHP
PHP中if和or运行效率对比
2014/12/12 PHP
PHP给前端返回一个JSON对象的实例讲解
2018/05/31 PHP
PHP实现长轮询消息实时推送功能代码实例讲解
2021/02/26 PHP
jQuery创建插件的代码分析
2011/04/14 Javascript
JQuery EasyUI学习教程之datagrid 添加、修改、删除操作
2016/07/09 Javascript
js中利用cookie实现记住密码功能
2020/08/20 Javascript
vue中渐进过渡效果实现
2016/10/27 Javascript
关于axios返回空对象的问题解决
2017/04/04 Javascript
JavaScript实现二叉树的先序、中序及后序遍历方法详解
2017/10/26 Javascript
Vue路由切换时的左滑和右滑效果示例
2018/05/29 Javascript
jQuery轻量级表单模型验证插件
2018/10/15 jQuery
Vue动态修改网页标题的方法及遇到问题
2019/06/09 Javascript
微信小程序 确认框的实现(附代码)
2019/07/23 Javascript
浅谈Vue3.0之前你必须知道的TypeScript实战技巧
2019/09/11 Javascript
[01:51]2018年度CS GO最具人气外援-完美盛典
2018/12/16 DOTA
python判断windows隐藏文件的方法
2014/03/21 Python
python使用Berkeley DB数据库实例
2014/09/26 Python
python数据结构之列表和元组的详解
2017/09/23 Python
Pandas:Series和DataFrame删除指定轴上数据的方法
2018/11/10 Python
python pygame实现2048游戏
2018/11/20 Python
对python3中, print横向输出的方法详解
2019/01/28 Python
Django如何开发简单的查询接口详解
2019/05/17 Python
python3 map函数和filter函数详解
2019/08/26 Python
python中count函数简单用法
2020/01/05 Python
浅谈keras的深度模型训练过程及结果记录方式
2020/01/24 Python
Python描述数据结构学习之哈夫曼树篇
2020/09/07 Python
python+selenium爬取微博热搜存入Mysql的实现方法
2021/01/27 Python
利用CSS3伪元素实现逐渐发光的方格边框
2017/05/07 HTML / CSS
你的自行车健身专家:FaFit24
2016/11/16 全球购物
关键字final的用法
2013/10/02 面试题
名词解释型面试题(主要是网络)
2013/12/27 面试题
鼓励运动员的广播稿
2014/02/08 职场文书
银行柜员优质服务心得体会
2016/01/22 职场文书
2019大学生暑期实习心得总结
2019/08/21 职场文书
导游词之湖北武当山
2019/09/23 职场文书