浅谈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 相关文章推荐
基于jquery的横向滚动条(滑动条)
Feb 24 Javascript
Google Dart编程语法和基本类型学习教程
Nov 27 Javascript
JS实现日期加减的方法
Nov 29 Javascript
javascript显示倒计时控制按钮的简单实现
Jun 07 Javascript
jQuery下拉框的简单应用
Jun 24 Javascript
js输出数据精确到小数点后n位代码
Jul 02 Javascript
基于jQuery的ajax方法封装
Jul 14 Javascript
微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解
Dec 08 Javascript
JS库particles.js创建超炫背景粒子插件(附源码下载)
Sep 13 Javascript
iview table高度动态设置方法
Mar 14 Javascript
js实现搜索提示框效果
Sep 05 Javascript
Vue+Bootstrap实现简易学生管理系统
Feb 09 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
PHPShop存在多个安全漏洞
2006/10/09 PHP
php 冒泡排序 交换排序法
2011/05/10 PHP
php组合排序简单实现方法
2016/10/15 PHP
php 命名空间(namespace)原理与用法实例小结
2019/11/13 PHP
jQuery ui插件的使用方法代码实例
2013/05/08 Javascript
EasyUi datagrid 实现表格分页
2015/02/10 Javascript
简介JavaScript中的setTime()方法的使用
2015/06/11 Javascript
javascript匀速动画和缓冲动画详解
2016/10/20 Javascript
微信小程序页面开发注意事项整理
2017/05/18 Javascript
JavaScript中字符串的常用操作方法及特殊字符
2018/03/18 Javascript
微信小程序实现单个卡片左滑显示按钮并防止上下滑动干扰功能
2019/12/06 Javascript
[40:13]Ti4 冒泡赛第二天 iG vs NEWBEE 2
2014/07/15 DOTA
[44:10]2018DOTA2亚洲邀请赛 4.5 淘汰赛 EG vs VP 第一场
2018/04/06 DOTA
Python使用smtplib模块发送电子邮件的流程详解
2016/06/27 Python
djano一对一、多对多、分页实例代码
2019/08/16 Python
np.random.seed() 的使用详解
2020/01/14 Python
python Scrapy框架原理解析
2021/01/04 Python
英国领先的品牌珠宝和配件供应商:Acotis Jewellery
2018/03/07 全球购物
Haggar官网:美国男装品牌
2020/02/16 全球购物
现在输入n个数字,以逗号,分开;然后可选择升或者降序排序;按提交键就在另一页面显示按什么排序,结果为,提供reset
2012/11/09 面试题
质检的岗位职责
2013/11/17 职场文书
辩论赛主持词
2014/03/18 职场文书
李敖北大演讲稿
2014/05/24 职场文书
人民调解员培训方案
2014/06/05 职场文书
人事经理岗位职责范本
2014/08/04 职场文书
事业单位个人查摆问题及整改措施
2014/10/28 职场文书
大学生实训报告总结
2014/11/05 职场文书
导游词欢迎词
2015/02/02 职场文书
党员活动总结
2015/02/04 职场文书
罚款通知怎么写
2015/04/22 职场文书
2015初一年级组工作总结
2015/07/24 职场文书
优胜劣汰,强者为王——读《鲁滨逊漂流记》有感
2019/08/15 职场文书
慰问信(范文3篇)
2019/10/23 职场文书
JavaScript模拟实现网易云轮播效果
2022/04/04 Javascript
python数字图像处理:图像简单滤波
2022/06/28 Python
Python中tqdm的使用和例子
2022/09/23 Python