Vue 数据绑定的原理分析


Posted in Javascript onNovember 16, 2020

原理

其实原理很简单,就是拦截了Object的get/set方法,在对数据进行set(obj.aget=18)时去重现渲染视图

实现方式有两种

  • 方式1

定义了同名的get/set就相当于定义了age

var test = {
   _age: 18,
   get age() {
     console.log('触发get');
     //直接会this.age会进入死递归的
     return this._age;
   },
   set age(age) {
     console.log('触发set');
     this._age = age;
   }
 };

为了让test不显示多余的变量,可以把_age定义在外部

var _age = 18;
 var test = {
   get age() {
     console.log('触发get');
     //直接会this.age会进入死递归的
     return _age;
   },
   set age(age) {
     console.log('触发set');
     _age = age;
   }
 };
  • 方式2

使用这种方式完美的解决了对象内包含多余的变量的问题

function test() {
   var _age = 18;
   Object.defineProperty(this, "age", {
     get: function () {
       console.log('触发get');
       return _age;
     },
     set: function (value) {
       console.log('触发set')
       _age = value;
     }
   });
 }
 var t = new test();
 t.age=18;

实现数据到视图的绑定

这里的渲染只是一个简单的正则替换

要实现Vue那么强大的功能还要自己实现一个模板引擎

Vue 数据绑定的原理分析

<div id="test">
  <p>name:</p>
  <p>age:</p>
</div>
function Element(id, initData) {
  var self = this;
  var el = document.getElementById(id);
  var templet = el.innerHTML;
  var _data = null;

  if (initData) {
    _data = {};
    for (var variable in initData) {
      _data[variable] = initData[variable];
      bind(variable, self);
    }
  }

  function bind(variable, obj) {
    Object.defineProperty(self, variable, {
      set: function (value) {
        //使用_data里的数据,避免死递归
        _data[variable] = value;
        //每次被设置新值的时候重新渲染界面
        render();
      },
      get: function () {
        return _data[variable];
      },
    });
  }

  //渲染
  function render() {
    var temp = templet;
    temp = temp.replace(/\{\{(.*)\}\}/g, function (s, t) {
      if (_data[t]) {
        return _data[t];
      }
    });
    el.innerHTML = temp;
  }

  //初始化时候手动渲染一次
  render();
}

var app = new Element('test', {
  name: 'zhangsan',
  age: 18
})

实现视图到数据的绑定

这里做一个简单的input改变的事件监听

每次渲染之后都要重新添加事件,用时间委托可以实现,但是input的focus位置不能保留

可见Vue内部的渲染和事件绑定肯定不是像这里demo写的那么简单,这里只是大致的原理(可能并不是这样的。。。)

Vue 数据绑定的原理分析

<div id="test">
  <input type="text" value="">
  <br>
  <span></span>
</div>
function Element(id, initData) {
  var self = this;
  var el = document.getElementById(id);
  var templet = el.innerHTML;
  var input = el.getElementsByTagName('input')[0];
  var _data = initData;

  Object.defineProperty(self, 'data', {
    set: function (value) {
      _data = value;
      render();
    },
    get: function () {
      return _data;
    },
  });

  //渲染
  function render() {
    var temp = templet;
    temp = temp.replace(/\{\{(data)\}\}/g, function (s, t) {
      return _data;
    });
    el.innerHTML = temp;

    //重新添加事件,其实应该用事件委托的
    input = el.getElementsByTagName('input')[0];
    inputchange();
    input.focus();
  }

  function inputchange() {
    if (window.attachEvent) {
      input.attachEvent("oninput", temp);
    } else if (window.addEventListener) {
      input.addEventListener("input", temp, false);
    }

    function temp() {
      self.data = input.value;
    }
  }

  //初始化时候手动渲染一次
  render();
}
var app = new Element('test', '');

以上就是Vue 数据绑定的原理分析的详细内容,更多关于Vue 数据绑定的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
jQuery 1.3 和 Validation 验证插件1.5.1
Jul 09 Javascript
jQuery的实现原理的模拟代码 -2 数据部分
Aug 01 Javascript
Jquery 自定义动画概述及示例
Mar 29 Javascript
Egret引擎开发指南之视觉编程
Sep 03 Javascript
深入JavaScript高级程序设计之对象、数组(栈方法,队列方法,重排序方法,迭代方法)
Dec 01 Javascript
BootStrap表单验证 FormValidation 调整反馈图标位置的实例代码
May 17 Javascript
JS获取填报扩展单元格控件的值的解决办法
Jul 14 Javascript
vue系列之动态路由详解【原创】
Sep 10 Javascript
微信小程序picker组件简单用法示例【附demo源码下载】
Dec 05 Javascript
Vue框架里使用Swiper的方法示例
Sep 20 Javascript
基于Vue-cli快速搭建项目的完整步骤
Nov 03 Javascript
JavaScript实现滚动加载更多
Dec 27 Javascript
Vue 使用iframe引用html页面实现vue和html页面方法的调用操作
Nov 16 #Javascript
Vue指令实现OutClick的示例
Nov 16 #Javascript
浅谈vue在html中出现{{}}的原因及解决方式
Nov 16 #Javascript
vue组件中传值EventBus的使用及注意事项说明
Nov 16 #Javascript
小程序自定义弹框效果
Nov 16 #Javascript
vuex中遇到的坑,vuex数据改变,组件中页面不渲染操作
Nov 16 #Javascript
基于Vue+Webpack拆分路由文件实现管理
Nov 16 #Javascript
You might like
谈谈新手如何学习PHP
2006/12/23 PHP
PHP采集腾讯微博的实现代码
2012/01/19 PHP
PHP中Memcache操作类及用法实例
2014/12/12 PHP
两种php去除二维数组的重复项方法
2015/11/04 PHP
php文件上传的两种实现方法
2016/04/04 PHP
PHP5.3连接Oracle客户端及PDO_OCI模块的安装方法
2016/05/13 PHP
Yii2主题(Theme)用法详解
2016/07/23 PHP
php中如何执行linux命令详解
2018/11/06 PHP
php 实现银联商务H5支付的示例代码
2019/10/12 PHP
JavaScript 核心参考教程 内置对象
2009/10/13 Javascript
浅析jQuery的链式调用之each函数
2010/12/03 Javascript
JavaScript实现自己的DOM选择器原理及代码
2013/03/04 Javascript
很好用的js日历算法详细代码
2013/03/07 Javascript
js substr支持中文截取函数代码(中文是双字节)
2013/04/17 Javascript
28个常用JavaScript方法集锦
2015/01/14 Javascript
两行代码轻松搞定JavaScript日期验证
2016/08/03 Javascript
jQuery实现弹出窗口弹出div层的实例代码
2017/01/09 Javascript
JS数组实现分类统计实例代码
2018/09/30 Javascript
微信小程序自定义弹窗滚动与页面滚动冲突的解决方法
2019/07/16 Javascript
使用python实现接口的方法
2017/07/07 Python
Python爬取当当、京东、亚马逊图书信息代码实例
2017/12/09 Python
python语言中with as的用法使用详解
2018/02/23 Python
python 识别图片中的文字信息方法
2018/05/10 Python
Python实现爬虫抓取与读写、追加到excel文件操作示例
2018/06/27 Python
Python面向对象之反射/自省机制实例分析
2018/08/24 Python
Python自动化运维之Ansible定义主机与组规则操作详解
2019/06/13 Python
python使用sklearn实现决策树的方法示例
2019/09/12 Python
Python基于数列实现购物车程序过程详解
2020/06/09 Python
CSS3 rgb and rgba(透明色)的使用详解
2020/09/25 HTML / CSS
html5中localStorage本地存储的简单使用
2017/06/16 HTML / CSS
J2EE面试题集锦(附答案)
2013/08/16 面试题
小学三好学生事迹材料
2014/08/15 职场文书
2014党员学习《反腐倡廉警示教育读本》思想汇报
2014/09/13 职场文书
2014年安全员工作总结
2014/11/13 职场文书
2014年民警工作总结
2014/11/25 职场文书
餐饮服务员岗位职责
2015/02/09 职场文书