浅谈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 相关文章推荐
js技巧--转义符&quot;\&quot;的妙用
Jan 09 Javascript
前端必备神器 Snap.svg 弹动效果
Nov 10 Javascript
JS模式之单例模式基本用法
Jun 30 Javascript
jQuery弹层插件jquery.fancybox.js用法实例
Jan 22 Javascript
jQuery简单自定义图片轮播插件及用法示例
Nov 21 Javascript
如何处理JSON中的特殊字符
Nov 30 Javascript
JS实现物体带缓冲的间歇运动效果示例
Dec 22 Javascript
关于webpack2和模块打包的新手指南(小结)
Aug 07 Javascript
原生JS实现获取及修改CSS样式的方法
Sep 04 Javascript
在vue项目中使用md5加密的方法
Sep 14 Javascript
vue-quill-editor+plupload富文本编辑器实例详解
Oct 19 Javascript
原生js添加一个或多个类名的方法分析
Jul 30 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
dede3.1分页文字采集过滤规则详说(图文教程)续二
2007/04/03 PHP
基于php 随机数的深入理解
2013/06/05 PHP
php写app接口并返回json数据的实例(分享)
2017/05/20 PHP
Javascript 继承机制实例
2009/08/12 Javascript
jquery json 实例代码
2010/12/02 Javascript
javascript学习笔记(二十) 获得和设置元素的特性(属性)
2012/06/20 Javascript
html a标签-超链接中confirm方法使用介绍
2013/01/04 Javascript
jquery js 获取时间差、时间格式具体代码
2013/06/05 Javascript
浅析JavaScript原型继承的陷阱
2013/12/03 Javascript
Node.js中对通用模块的封装方法
2014/06/06 Javascript
使用js画图之正弦曲线
2015/01/12 Javascript
基于jQuery实现仿淘宝套餐选择插件
2015/03/04 Javascript
代码分析jQuery四种静态方法使用
2015/07/23 Javascript
jQuery实现摸拟alert提示框
2016/05/22 Javascript
javascript之with的使用(阿里云、淘宝使用代码分析)
2016/10/11 Javascript
AngularJS中transclude用法详解
2016/11/03 Javascript
JS编写函数实现对身份证号码最后一位的验证功能
2016/12/29 Javascript
Bootstrap表单简单实现代码
2017/03/06 Javascript
jQuery+C#实现参数RSA加密传输功能【附jsencrypt.js下载】
2017/06/26 jQuery
使用vue-cli3 创建vue项目并配置VS Code 自动代码格式化 vue语法高亮问题
2019/05/14 Javascript
将Python代码打包为jar软件的简单方法
2015/08/04 Python
Python3实现的简单验证码识别功能示例
2018/05/02 Python
Python实现的本地文件搜索功能示例【测试可用】
2018/05/30 Python
详解python数据结构和算法
2019/04/18 Python
pyqt实现.ui文件批量转换为对应.py文件脚本
2019/06/19 Python
详解使用Python下载文件的几种方法
2019/10/13 Python
英语专业毕业生自我鉴定
2013/11/09 职场文书
前台文员个人求职信范文
2014/01/05 职场文书
服务员自我评价
2014/01/25 职场文书
三个儿子教学反思
2014/02/03 职场文书
感恩教育月活动总结
2014/07/07 职场文书
2014年资料员工作总结
2014/11/18 职场文书
辩论会主持词
2015/07/03 职场文书
企业年会祝酒词
2015/08/11 职场文书
Python爬取科目四考试题库的方法实现
2021/03/30 Python
CSS 实现多彩、智能的阴影效果
2021/05/12 HTML / CSS