浅谈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 相关文章推荐
下载站控制介绍字数显示的脚本 显示全部 隐藏介绍等功能
Sep 19 Javascript
解决用jquery load加载页面到div时,不执行页面js的问题
Feb 22 Javascript
js打造数组转json函数
Jan 14 Javascript
JavaScript的Date()方法使用详解
Jun 09 Javascript
JQuery实现网页右侧随动广告特效
Jan 17 Javascript
jquery获取img的src值的简单实例
May 17 Javascript
jQuery点击输入框显示验证码图片
May 19 Javascript
Bootstrap图片轮播组件使用实例解析
Jun 30 Javascript
javascript中异常处理案例(推荐)
Oct 03 Javascript
Vue项目引进ElementUI组件的方法
Nov 11 Javascript
JavaScript队列结构Queue实现过程解析
Mar 07 Javascript
jquery实现烟花效果(面向对象)
Mar 10 jQuery
让网站自动生成章节目录索引的多个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中处理模拟rewrite 效果
2006/12/09 PHP
php若干单维数组遍历方法的比较
2011/09/20 PHP
关于使用coreseek并为其做分页的介绍
2013/06/21 PHP
PHP 设计模式系列之 specification规格模式
2016/01/10 PHP
ThinkPHP框架中使用Memcached缓存数据的方法
2018/03/31 PHP
prototype Element学习笔记(篇一)
2008/10/26 Javascript
javascript结合html5 canvas实现(可调画笔颜色/粗细/橡皮)的涂鸦板
2013/04/27 Javascript
JQuery之focus函数使用介绍
2013/08/20 Javascript
使用javascript实现json数据以csv格式下载
2015/01/09 Javascript
jQuery实现在最后一个元素之前插入新元素的方法
2015/07/18 Javascript
跟我学习javascript的call(),apply(),bind()与回调
2015/11/16 Javascript
JS原型、原型链深入理解
2016/02/27 Javascript
javaScript如何跳出多重循环break、continue
2016/09/01 Javascript
javascript学习之json入门
2016/12/22 Javascript
JavaScript实现的XML与JSON互转功能详解
2017/02/16 Javascript
JS表单数据验证的正则表达式(常用)
2017/02/18 Javascript
windows下vue.js开发环境搭建教程
2017/03/20 Javascript
浅析vue中常见循环遍历指令的使用 v-for
2018/04/18 Javascript
vue实现信息管理系统
2020/05/30 Javascript
python生成器的使用方法
2013/11/21 Python
使用Python的Tornado框架实现一个一对一聊天的程序
2015/04/25 Python
Python的Flask框架中集成CKeditor富文本编辑器的教程
2016/06/13 Python
Python3中内置类型bytes和str用法及byte和string之间各种编码转换 问题
2018/09/27 Python
如何基于Python + requests实现发送HTTP请求
2020/01/13 Python
Python自动化测试笔试面试题精选
2020/03/12 Python
python如何求圆的面积
2020/07/01 Python
django 将自带的数据库sqlite3改成mysql实例
2020/07/09 Python
python七种方法判断字符串是否包含子串
2020/08/18 Python
在HTML5中使用MathML数学公式的简单讲解
2016/02/19 HTML / CSS
中学生社会实践活动总结
2014/07/03 职场文书
学校总务处领导班子民主生活会对照检查材料思想汇报
2014/09/27 职场文书
市场督导岗位职责
2015/04/10 职场文书
村级干部党员公开承诺事项
2015/05/04 职场文书
2015暑假社会调查报告
2015/07/13 职场文书
修改并编译golang源码的操作步骤
2021/07/25 Golang
使用RedisTemplat实现简单的分布式锁
2021/11/20 Redis