全面解析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 相关文章推荐
node.js chat程序如何实现Ajax long-polling长链接刷新模式
Mar 13 Javascript
javascript打印大全(打印页面设置/打印预览代码)
Mar 29 Javascript
js创建子窗口并且回传值示例代码
Jul 02 Javascript
js返回前一页刷新本页重载页面
Jul 29 Javascript
JavaScript设置body高度为浏览器高度的方法
Feb 09 Javascript
解决bootstrap中modal遇到Esc键无法关闭页面
Mar 09 Javascript
详解JavaScript 中的 replace 方法
Jan 01 Javascript
BootStrap智能表单实战系列(四)表单布局介绍
Jun 13 Javascript
Angularjs中ng-repeat-start与ng-repeat-end的用法实例介绍
Dec 31 Javascript
js分页之前端代码实现和请求处理
Aug 04 Javascript
vue v-model动态生成详解
Jun 30 Javascript
element ui table(表格)实现点击一行展开功能
Dec 04 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
造就帕卡马拉的帕卡斯是怎么被发现的
2021/03/03 咖啡文化
PHP个人网站架设连环讲(四)
2006/10/09 PHP
自编函数解决pathinfo()函数处理中文问题
2014/11/03 PHP
php生成4位数字验证码的实现代码
2015/11/23 PHP
PHP  实现等比压缩图片尺寸和大小实例代码
2016/10/08 PHP
window.onload 加载完毕的问题及解决方案(上)
2009/07/09 Javascript
JS 有名函数表达式全面解析
2010/03/19 Javascript
JQuery调webservice实现邮箱验证(检测是否可用)
2013/05/21 Javascript
jQuery使用andSelf()来包含之前的选择集
2014/05/19 Javascript
分享bootstrap学习笔记心得(组件及其属性)
2017/01/11 Javascript
详解Angular-cli生成组件修改css成less或sass的实例
2017/07/27 Javascript
小程序实现多选框功能
2018/10/30 Javascript
Vue项目引发的「过滤器」使用教程
2019/03/12 Javascript
vuex + keep-alive实现tab标签页面缓存功能
2019/10/17 Javascript
js 将多个对象合并成一个对象 assign方法的实现
2020/09/24 Javascript
[03:42]2014DOTA2西雅图国际邀请赛 Navi战队巡礼
2014/07/07 DOTA
[01:58]DOTA2上海特级锦标赛现场采访:RTZ这个ID到底好不好
2016/03/25 DOTA
给Python初学者的一些编程技巧
2015/04/03 Python
python实现的简单RPG游戏流程实例
2015/06/28 Python
python numpy 部分排序 寻找最大的前几个数的方法
2018/06/27 Python
对Python subprocess.Popen子进程管道阻塞详解
2018/10/29 Python
Python List cmp()知识点总结
2019/02/18 Python
python处理“
2019/06/10 Python
Python小程序之在图片上加入数字的代码
2019/11/26 Python
Python实现进度条和时间预估的示例代码
2020/06/02 Python
HTML5在IE10、火狐下中文乱码问题的解决方法
2013/11/18 HTML / CSS
跑步爱好者一站式服务网站:Jack Rabbit
2016/09/01 全球购物
Sandro Paris美国官网:典雅别致的法国时尚服饰品牌
2017/12/26 全球购物
中专毕业生自荐信
2013/11/16 职场文书
税务会计岗位职责
2014/02/18 职场文书
艺术学院毕业生自我评价
2014/03/02 职场文书
物业公司的岗位任命书
2014/06/06 职场文书
小学综合实践活动总结
2014/07/07 职场文书
行政诉讼答辩状
2015/05/21 职场文书
Python实现Matplotlib,Seaborn动态数据图
2022/05/06 Python
详解Go语言中Get/Post请求测试
2022/06/01 Golang