浅谈Vue数据绑定的原理


Posted in Javascript onJanuary 08, 2018

本文介绍了Vue数据绑定的原理,分享给大家,具体如下:

原理

其实原理很简单,就是拦截了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', '');

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
编辑浪子版表单验证类
May 12 Javascript
JavaScript让IE浏览器event对象符合W3C DOM标准
Nov 24 Javascript
加载 Javascript 最佳实践
Oct 30 Javascript
javascript获取作用在元素上面的样式属性代码
Sep 20 Javascript
JS中的this变量的使用介绍
Oct 21 Javascript
JS实现的新浪微博大厅文字内容滚动效果代码
Nov 05 Javascript
js实现上传图片预览方法
Oct 25 Javascript
javascript计算对象长度的方法
Oct 25 Javascript
vue表单验证你真的会了吗?vue表单验证(form)validate
Apr 07 Javascript
javascript数据类型中的一些小知识点(推荐)
Apr 18 Javascript
微信小程序之下拉列表实现方法解析(附完整源码)
Aug 23 Javascript
vue 通过绑定事件获取当前行的id操作
Jul 27 Javascript
让网站自动生成章节目录索引的多个js代码
Jan 07 #Javascript
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
Jan 07 #Javascript
Bootstrap treeview实现动态加载数据并添加快捷搜索功能
Jan 07 #Javascript
vue实现登录后页面跳转到之前页面
Jan 07 #Javascript
Nginx 配置多站点vhost 的方法
Jan 07 #Javascript
express+mockjs实现模拟后台数据发送功能
Jan 07 #Javascript
使用mock.js随机数据和使用express输出json接口的实现方法
Jan 07 #Javascript
You might like
php编程实现获取excel文档内容的代码实例
2011/06/28 PHP
php数组函数序列之krsort()- 对数组的元素键名进行降序排序,保持索引关系
2011/11/02 PHP
探讨PHP调用时间格式的参数详解
2013/06/06 PHP
php中的静态变量的基本用法
2014/03/20 PHP
php与python实现的线程池多线程爬虫功能示例
2016/10/12 PHP
Laravel 实现数据软删除功能
2019/08/21 PHP
php ActiveMQ的安装与使用方法图文教程
2020/02/23 PHP
JS中Iframe之间传值的方法
2013/03/11 Javascript
Jquery的hide及toggle方法让超链接慢慢消失
2013/09/06 Javascript
PHPExcel中的一些常用方法汇总
2015/01/23 Javascript
js实现鼠标点击左上角滑动菜单效果代码
2015/09/06 Javascript
js与applet相互调用的方法
2016/06/22 Javascript
JavaScript学习小结之使用canvas画“哆啦A梦”时钟
2016/07/24 Javascript
js实现移动端微信页面禁止字体放大
2017/02/16 Javascript
js 转义字符及URI编码详解
2017/02/28 Javascript
Bootstrap弹出框之自定义悬停框标题、内容和样式示例代码
2017/07/11 Javascript
dropload.js插件下拉刷新和上拉加载使用详解
2017/10/20 Javascript
详解微信小程序审核不通过的解决方法
2018/01/17 Javascript
微信小程序scroll-view组件实现滚动动画
2018/01/31 Javascript
详解Axios 如何取消已发送的请求
2018/10/20 Javascript
微信小程序实现上传word、txt、Excel、PPT等文件功能
2019/05/23 Javascript
LayUi使用switch开关,动态的去控制它是否被启用的方法
2019/09/21 Javascript
[46:37]LGD vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
python将字典内容存入mysql实例代码
2018/01/18 Python
python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧装饰器信号与槽详细使用方法与实例
2020/03/06 Python
python可以用哪些数据库
2020/06/22 Python
使用ITK-SNAP进行抠图操作并保存mask的实例
2020/07/01 Python
详解Open Folder as PyCharm Project怎么添加的方法
2020/12/29 Python
html5中如何将图片的绝对路径转换成文件对象
2018/01/11 HTML / CSS
Linux内核产生并发的原因
2012/07/13 面试题
学生会主席竞聘书
2014/03/31 职场文书
2014年档案管理工作总结
2014/11/17 职场文书
2015年教师节活动总结
2015/03/20 职场文书
运动会通讯稿200字
2015/07/20 职场文书
python字典进行运算原理及实例分享
2021/08/02 Python
Python3.8官网文档之类的基础语法阅读
2021/09/04 Python