全面解析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 相关文章推荐
你真的了解JavaScript吗?
Feb 24 Javascript
IE下通过a实现location.href 获取referer的值
Sep 04 Javascript
javascript内置对象操作详解
Feb 04 Javascript
javascript中setInterval的用法
Jul 19 Javascript
JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法
Apr 28 Javascript
Vue2.0实现将页面中表格数据导出excel的实例
Aug 09 Javascript
vue父组件通过props如何向子组件传递方法详解
Aug 16 Javascript
使用js获取伪元素的content实例
Oct 24 Javascript
Vue.js的动态组件模板的实现
Nov 26 Javascript
Vue从TodoList中学父子组件通信
Feb 05 Javascript
vue实现前台列表数据过滤搜索、分页效果
May 28 Javascript
jquery 插件重新绑定的处理方法分析
Nov 23 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
yii框架结合charjs统计上一年与当前年数据的方法示例
2020/04/04 PHP
Javascript注入技巧
2007/06/22 Javascript
flash 得到自身url参数的代码
2009/11/15 Javascript
Javascript之旅 对象的原型链之由来
2010/08/25 Javascript
Jquery跨域获得Json时invalid label错误的解决办法
2011/01/11 Javascript
javascript背景时钟实现方法
2015/06/18 Javascript
jquery地址栏链接与a标签链接匹配之特效代码总结
2015/08/24 Javascript
js读取并解析JSON类型数据的方法
2015/11/14 Javascript
基于Jquery和html5实现炫酷的3D焦点图动画
2016/03/02 Javascript
jQuery实现左侧导航模块的显示与隐藏效果
2016/07/04 Javascript
Vue.js快速入门实例教程
2016/10/15 Javascript
JS Select下拉框(支持输入模糊查询)
2017/02/04 Javascript
Vue数组更新及过滤排序功能
2017/08/10 Javascript
three.js实现3D视野缩放效果
2017/11/16 Javascript
解决vue项目打包后提示图片文件路径错误的问题
2018/07/04 Javascript
vue 详情跳转至列表页实现列表页缓存
2019/03/27 Javascript
解决vue字符串换行问题(绝对管用)
2020/08/06 Javascript
如何利用JavaScript编写更好的条件语句详解
2020/08/10 Javascript
[01:01:41]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Magma BO3 第二场 1月31日
2021/03/11 DOTA
为python设置socket代理的方法
2015/01/14 Python
Python中使用socket发送HTTP请求数据接收不完整问题解决方法
2015/02/04 Python
Python 修改列表中的元素方法
2018/06/26 Python
python opencv旋转图像(保持图像不被裁减)
2018/07/26 Python
python3 字符串知识点学习笔记
2020/02/08 Python
Marc Jacobs彩妆官网:Marc Jacobs Beauty
2017/07/03 全球购物
华纳兄弟工作室的官方授权商店:WB Shop
2018/11/30 全球购物
YSL圣罗兰美妆英国官网:Yves Saint Laurent Beauty UK
2019/08/03 全球购物
应届生会计电算化求职信
2013/10/03 职场文书
奥巴马开学演讲稿
2014/05/15 职场文书
工作所在部门证明
2014/09/21 职场文书
会计岗位工作总结
2015/08/12 职场文书
2016年共产党员公开承诺书
2016/03/24 职场文书
利用html+css实现菜单栏缓慢下拉效果的示例代码
2021/03/30 HTML / CSS
教你做个可爱的css滑动导航条
2021/06/15 HTML / CSS
Python语法学习之进程的创建与常用方法详解
2022/04/08 Python
Golang MatrixOne使用介绍和汇编语法
2022/04/19 Golang