浅谈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的gzip静态压缩方法
Jan 05 Javascript
javascript中关于执行环境的杂谈
Aug 14 Javascript
JavaScript设计模式学习之“类式继承”
Mar 12 Javascript
javascript实现2016新年版日历
Jan 25 Javascript
jQuery通过ajax快速批量提交表单数据
Oct 25 Javascript
任意Json转成无序列表的方法示例
Dec 09 Javascript
JQuery Dialog对话框 不能通过Esc关闭的原因分析及解决办法
Jan 18 Javascript
对vue 键盘回车事件的实例讲解
Aug 25 Javascript
jQuery解析json格式数据示例
Sep 01 jQuery
Vue 的双向绑定原理与用法揭秘
May 06 Javascript
vue设置默认首页的操作
Aug 12 Javascript
vue实现登陆页面开发实践
May 30 Vue.js
让网站自动生成章节目录索引的多个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
Linux Apache PHP Oracle 安装配置(具体操作步骤)
2013/06/17 PHP
php Session存储到Redis的方法
2013/11/04 PHP
php分页示例分享
2014/04/30 PHP
smarty中英文多编码字符截取乱码问题解决方法
2014/10/28 PHP
WordPress迁移时一些常见问题的解决方法整理
2015/11/24 PHP
PHP实现SMTP邮件的发送实例
2018/09/27 PHP
setInterval 和 setTimeout会产生内存溢出
2008/02/15 Javascript
jQuery 顺便学习下CSS选择器 奇偶匹配nth-child(even)
2010/05/24 Javascript
基于jQuery的树控件实现代码(asp.net+json)
2010/07/11 Javascript
使用jQuery重置(reset)表单的方法
2014/05/05 Javascript
javascript实现的全国省市县无刷新多级关联菜单效果代码
2016/08/01 Javascript
基于javascript的Form表单验证
2016/12/29 Javascript
webpack配置sass模块的加载的方法
2017/07/30 Javascript
关于jquery layui弹出层的使用方法
2018/04/21 jQuery
微信小程序购物车、父子组件传值及calc的注意事项总结
2018/11/14 Javascript
用vscode开发vue应用的方法步骤
2019/05/06 Javascript
详解vuex的简单todolist例子
2019/07/14 Javascript
vue使用Sass时报错问题的解决方法
2020/10/14 Javascript
Python中的Classes和Metaclasses详解
2015/04/02 Python
利用python微信库itchat实现微信自动回复功能
2017/05/18 Python
详解tensorflow训练自己的数据集实现CNN图像分类
2018/02/07 Python
Python3导入自定义模块的三种方法详解
2018/04/13 Python
关于django 数据库迁移(migrate)应该知道的一些事
2018/05/27 Python
Python将字符串常量转化为变量方法总结
2019/03/17 Python
Python制作词云图代码实例
2019/09/09 Python
利用CSS3的transform做的动态时钟效果
2011/09/21 HTML / CSS
css3实现多个元素依次显示效果
2017/12/12 HTML / CSS
百思买加拿大:Best Buy Canada
2018/03/20 全球购物
美国高档帽子网上商店:Hats.com
2018/08/09 全球购物
优秀的计算机专业求职信范文
2013/12/27 职场文书
小学优秀班主任事迹材料
2014/05/17 职场文书
2014学习优秀共产党员先进事迹材料思想汇报
2014/09/14 职场文书
班子查摆四风个人对照检查材料思想汇报
2014/10/04 职场文书
Python 使用dict实现switch的操作
2021/04/07 Python
sql server 累计求和实现代码
2022/02/28 SQL Server
Python matplotlib 利用随机函数生成变化图形
2022/04/26 Python