浅谈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 字符 Escape,encodeURI,encodeURIComponent
Jul 09 Javascript
JSON 学习之JSON in JavaScript详细使用说明
Feb 23 Javascript
浅谈javascript中onbeforeunload与onunload事件
Dec 10 Javascript
JavaScript中各种引用类型的常用操作方法小结
May 05 Javascript
jQuery mobile的header和footer在点击屏幕的时候消失的解决办法
Jul 01 Javascript
Javascript生成带参数的二维码示例
Oct 10 Javascript
Jquery Easyui对话框组件Dialog使用详解(14)
Dec 19 Javascript
javaScript中封装的各种写法示例(推荐)
Jul 03 Javascript
vue项目常用组件和框架结构介绍
Dec 24 Javascript
JavaScript的数据类型转换原则(干货)
Mar 15 Javascript
深入浅析Vue中的slots/scoped slots
Apr 03 Javascript
超轻量级的js时间库miment使用解析
Aug 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中加session验证)
2012/08/22 PHP
PHP面向对象程序设计OOP继承用法入门示例
2016/12/27 PHP
PHP调用API接口实现天气查询功能的示例
2017/09/21 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
2018/02/08 PHP
PHP数组array类常见操作示例
2020/05/15 PHP
一个可拖拽列宽表格实例演示
2012/11/26 Javascript
用JQuery 判断某个属性是否存在hasAttr的解决方法
2013/04/26 Javascript
js处理表格对table进行修饰
2014/05/26 Javascript
javascript实现dom动态创建省市纵向列表菜单的方法
2015/05/14 Javascript
基于BootStrap实现简洁注册界面
2017/07/20 Javascript
基于 Vue.js 2.0 酷炫自适应背景视频登录页面实现方式
2018/01/17 Javascript
jQuery实现模糊搜索功能的方法分析
2018/06/29 jQuery
跟老齐学Python之编写类之四再论继承
2014/10/11 Python
Python使用百度API上传文件到百度网盘代码分享
2014/11/08 Python
详细讲解Python中的文件I/O操作
2015/05/24 Python
Python复制文件操作实例详解
2015/11/10 Python
举例讲解Python设计模式编程中对抽象工厂模式的运用
2016/03/02 Python
python获取list下标及其值的简单方法
2016/09/12 Python
python3.6连接MySQL和表的创建与删除实例代码
2017/12/28 Python
python与sqlite3实现解密chrome cookie实例代码
2018/01/20 Python
Python实现的rsa加密算法详解
2018/01/24 Python
Django中针对基于类的视图添加csrf_exempt实例代码
2018/02/11 Python
django+xadmin+djcelery实现后台管理定时任务
2018/08/14 Python
Python实现的旋转数组功能算法示例
2019/02/23 Python
基于python实现判断字符串是否数字算法
2020/07/10 Python
python自动化测试三部曲之unittest框架的实现
2020/10/07 Python
CSS3模拟IOS滑动开关效果
2016/09/28 HTML / CSS
大学生个人求职信范文
2013/09/21 职场文书
不打扫卫生检讨书
2014/02/12 职场文书
药品促销活动方案
2014/02/14 职场文书
大学校务公开实施方案
2014/03/31 职场文书
成绩单公证书
2014/04/10 职场文书
2014年药店店长工作总结
2014/11/17 职场文书
大学生党课心得体会
2016/01/07 职场文书
python非标准时间的转换
2021/07/25 Python
SONY AN-LP1 短波有源天线放大器图
2022/04/05 无线电