浅谈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 23 Javascript
js获取客户端外网ip的简单实例
Nov 21 Javascript
js 对小数加法精度处理示例说明
Dec 27 Javascript
兼容主流浏览器的JS复制内容到剪贴板
Dec 12 Javascript
jQuery中outerHeight()方法用法实例
Jan 19 Javascript
jquery获取及设置outerhtml的方法
Mar 09 Javascript
jQuery插件实现多级联动菜单效果
Dec 01 Javascript
javascript实现倒计时跳转页面
Jan 17 Javascript
jQuery设置聚焦并使光标位置在文字最后的实现方法
Aug 02 Javascript
关于AngularJs数据的本地存储详解
Jan 20 Javascript
JS Select下拉框(支持输入模糊查询)
Feb 04 Javascript
vue自定义插件封装,实现简易的elementUi的Message和MessageBox的示例
Nov 20 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
重置版宣传动画
2020/04/09 魔兽争霸
php修改文件上传限制方法汇总
2015/04/07 PHP
js中几种去掉字串左右空格的方法
2006/12/25 Javascript
jQuery的3种请求方式$.post,$.get,$.getJSON
2014/03/28 Javascript
用循环或if语句从json中取数据示例
2014/08/18 Javascript
如何调试异步加载页面里包含的js文件
2014/10/30 Javascript
使用jquery动态加载Js文件和Css文件
2015/10/24 Javascript
开源免费天气预报接口API及全国所有地区代码(国家气象局提供)
2016/12/26 Javascript
Javascript基础回顾之(三) js面向对象
2017/01/31 Javascript
setTimeout函数的神奇使用
2017/02/26 Javascript
Angular.js中定时器循环的3种方法总结
2017/04/27 Javascript
vue router demo详解
2017/10/13 Javascript
解决node-sass偶尔安装失败的方法小结
2018/12/05 Javascript
一起写一个即插即用的Vue Loading插件实现
2019/10/31 Javascript
使用Bootstrap做一个朝代历史表
2019/12/10 Javascript
js实现批量删除功能
2020/08/27 Javascript
js实现移动端图片滑块验证功能
2020/09/29 Javascript
Python变量作用范围实例分析
2015/07/07 Python
Python3将数据保存为txt文件的方法
2019/09/12 Python
pytorch: Parameter 的数据结构实例
2019/12/31 Python
python:目标检测模型预测准确度计算方式(基于IoU)
2020/01/18 Python
Python多重继承之菱形继承的实例详解
2020/02/12 Python
如何用Python 实现全连接神经网络(Multi-layer Perceptron)
2020/10/15 Python
Python使用grequests并发发送请求的示例
2020/11/05 Python
Python函数调用追踪实现代码
2020/11/27 Python
selenium携带cookies模拟登陆CSDN的实现
2021/01/19 Python
matplotlib之pyplot模块坐标轴标签设置使用(xlabel()、ylabel())
2021/02/22 Python
志愿者宣传口号
2014/06/17 职场文书
家庭教育的心得体会
2014/09/01 职场文书
黄石寨导游词
2015/02/05 职场文书
4S店收银员岗位职责
2015/04/07 职场文书
2019年暑期法院实习报告
2019/12/18 职场文书
创作书写之导游词实用技巧分享(干货)
2019/12/20 职场文书
Spring Data JPA使用JPQL与原生SQL进行查询的操作
2021/06/15 Java/Android
使用redis生成唯一编号及原理示例详解
2021/09/15 Redis
mysql通过group by分组取最大时间对应数据的两种有效方法
2022/09/23 MySQL