浅谈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 相关文章推荐
javascript编程起步(第三课)
Feb 27 Javascript
使用jQuery清空file文件域的解决方案
Apr 12 Javascript
对于this和$(this)的个人理解
Sep 08 Javascript
jQuery插件scroll实现无缝滚动效果
Apr 27 Javascript
js实现头像图片切割缩放及无刷新上传图片的方法
Jul 17 Javascript
vue登录路由验证的实现
Dec 13 Javascript
原生JS写Ajax的请求函数功能
Dec 22 Javascript
11行JS代码制作二维码生成功能
Mar 09 Javascript
React-router4路由监听的实现
Aug 07 Javascript
微信公众平台 发送模板消息(Java接口开发)
Apr 17 Javascript
小程序和web画三角形实现解析
Sep 02 Javascript
JavaScript实现雪花飘落效果
Dec 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上传文件时文件过大$_FILES为空的解决方法
2013/11/26 PHP
功能强大的PHP发邮件类
2016/08/29 PHP
PHP+MySQL实现消息队列的方法分析
2018/05/09 PHP
php中file_get_contents()函数用法实例
2019/02/21 PHP
Ubuntu 11.10 安装Node.js的方法
2011/11/30 Javascript
js Array对象的扩展函数代码
2013/04/24 Javascript
Jquery中给animation加更多的运作效果实例
2013/09/05 Javascript
教你如何使用firebug调试功能了解javascript闭包和this
2015/03/04 Javascript
javascript实现点击单选按钮链接转向对应网址的方法
2015/08/12 Javascript
javascript实现网站加入收藏功能
2015/12/16 Javascript
js中flexible.js实现淘宝弹性布局方案
2020/06/23 Javascript
jQuery操作属性和样式详解
2016/04/13 Javascript
原生JS实现的放大镜效果实例代码
2016/10/15 Javascript
JavaScript模仿Pinterest实现图片预加载功能
2016/10/25 Javascript
Node连接mysql数据库方法介绍
2017/02/07 Javascript
分分钟玩转Vue.js组件(二)
2017/03/01 Javascript
vue使用axios时关于this的指向问题详解
2017/12/22 Javascript
Nuxt.js的路由跳转操作(页面跳转nuxt-link)
2020/11/06 Javascript
[48:24]完美世界DOTA2联赛循环赛LBZS vs Forest 第一场 10月30日
2020/10/31 DOTA
python使用paramiko实现远程拷贝文件的方法
2016/04/18 Python
Python学习小技巧之列表项的推导式与过滤操作
2017/05/20 Python
Python实现希尔排序算法的原理与用法实例分析
2017/11/23 Python
Python Web框架之Django框架文件上传功能详解
2019/08/16 Python
pytorch实现用Resnet提取特征并保存为txt文件的方法
2019/08/20 Python
python中resample函数实现重采样和降采样代码
2020/02/25 Python
pytorch查看模型weight与grad方式
2020/06/24 Python
vscode配置anaconda3的方法步骤
2020/08/08 Python
翻新二手苹果产品的网络领导者:Mac of all Trades
2017/12/19 全球购物
Office DEPOT法国官网:欧迪办公用品采购
2018/01/03 全球购物
智能家居、吸尘器、滑板车、电动自行车网上购物:Geekmaxi
2021/01/18 全球购物
学前教育教师求职自荐信
2013/09/22 职场文书
三个儿子教学反思
2014/02/03 职场文书
秋季运动会广播稿大全
2014/02/17 职场文书
2014年师德承诺书
2014/05/23 职场文书
地陪导游欢迎词
2015/01/26 职场文书
党支部意见范文
2015/06/02 职场文书