浅谈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 相关文章推荐
html文本框提示效果的示例代码
Jun 28 Javascript
用JavaScript实现PHP的urlencode与urldecode函数
Aug 13 Javascript
正则表达式优化JSON字符串的技巧
Dec 24 Javascript
HTML5 实现的一个俄罗斯方块实例代码
Sep 19 Javascript
基于ajax与msmq技术的消息推送功能实现代码
Dec 26 Javascript
jQuery实现下拉菜单的实例代码
Jun 19 jQuery
Ionic3实现图片瀑布流布局
Aug 09 Javascript
JS实现百度搜索接口及链接功能实例代码
Feb 02 Javascript
关于vue路由缓存清除在main.js中的设置
Nov 06 Javascript
js判断非127开头的IP地址的实例代码
Jan 05 Javascript
js实现无缝轮播图
Mar 09 Javascript
如何将JavaScript将数组转为树形结构
Jun 02 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错误抑制符(@)导致引用传参失败Bug的分析
2011/05/02 PHP
PHP中error_reporting函数用法详细介绍
2017/06/11 PHP
php检测mysql表是否存在的方法小结
2017/07/20 PHP
JS中简单的实现像C#中using功能(有源码下载)
2007/01/09 Javascript
如何做到打开一个页面,过几分钟自动转到另一页面
2007/04/20 Javascript
javascript高级程序设计第二版第十二章事件要点总结(常用的跨浏览器检测方法)
2012/08/22 Javascript
JavaScript中的pow()方法使用详解
2015/06/15 Javascript
基于Jquery插件实现跨域异步上传文件功能
2016/04/26 Javascript
详解Javascript几种跨域方式总结
2017/02/27 Javascript
详解JS函数stack size计算方法
2018/06/18 Javascript
Vuex中的State使用介绍
2019/01/19 Javascript
vue路由对不同界面进行传参及跳转的总结
2019/04/20 Javascript
jQuery实现消息弹出框效果
2019/12/10 jQuery
javascript执行上下文、变量对象实例分析
2020/04/25 Javascript
javascript中的offsetWidth、clientWidth、innerWidth及相关属性方法
2020/05/14 Javascript
解决vue使用vant轮播组件swipe + flex时文字抖动问题
2021/01/07 Vue.js
[01:06]DOTA2隆重推出2016冬季勇士令状 内含上海特级锦标赛互动指南
2016/02/17 DOTA
python实现带声音的摩斯码翻译实现方法
2015/05/20 Python
python cx_Oracle模块的安装和使用详细介绍
2017/02/13 Python
用tensorflow实现弹性网络回归算法
2018/01/09 Python
Windows下将Python文件打包成.EXE可执行文件的方法
2018/08/03 Python
Python循环结构的应用场景详解
2019/07/11 Python
Python函数式编程指南:对生成器全面讲解
2019/11/19 Python
在python中创建指定大小的多维数组方式
2019/11/28 Python
python爬虫容易学吗
2020/06/02 Python
彪马西班牙官网:PUMA西班牙
2019/06/18 全球购物
TobyDeals美国:在电子产品上获得最好的优惠和折扣
2019/08/11 全球购物
酒店行政人事部经理职务说明书
2014/02/26 职场文书
运动会开幕式主持词
2014/03/28 职场文书
元旦寄语大全
2014/04/10 职场文书
《会走路的树》教后反思
2014/04/19 职场文书
大学生就业协议书范本(适用于公司企业)
2014/10/07 职场文书
自查自纠工作总结
2014/10/15 职场文书
经营场所使用证明
2015/06/19 职场文书
如何在Python项目中引入日志
2021/05/31 Python
golang使用map实现去除重复数组
2022/04/14 Golang