浅谈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 相关文章推荐
Node.js开发指南中的简单实例(mysql版)
Sep 17 Javascript
javascript使用百度地图api和html5特性获取浏览器位置
Jan 10 Javascript
node.js从数据库获取数据
May 08 Javascript
所见即所得的富文本编辑器bootstrap-wysiwyg使用方法详解
May 27 Javascript
通过jquery实现页面的动画效果(实例代码)
Sep 18 Javascript
详解Jquery Easyui的验证扩展
Jan 09 Javascript
js+canvas实现动态吃豆人效果
Mar 22 Javascript
JavaScript-定时器0~9抽奖系统详解(代码)
Aug 16 Javascript
关于JavaScript的单双引号嵌套问题
Aug 20 Javascript
Vue.js组件通信的几种姿势
Oct 23 Javascript
Vue.js 通过jQuery ajax获取数据实现更新后重新渲染页面的方法
Aug 09 jQuery
jQuery鼠标滑过横向时间轴样式(代码详解)
Nov 01 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+mysql写的留言本
2006/10/09 PHP
PHP数据集构建JSON格式及新数组的方法
2012/11/07 PHP
Codeigniter实现处理用户登录验证后的URL跳转
2014/06/12 PHP
PHP 传输会话curl函数的实例详解
2017/09/12 PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
2018/02/07 PHP
PHP迭代器和生成器用法实例分析
2019/09/28 PHP
Laravel框架实现定时Task Scheduling例子
2019/10/22 PHP
鼠标移动到一张图片时变为另一张图片
2006/12/05 Javascript
Javascript 代码也可以变得优美的实现方法
2009/06/22 Javascript
基于jquery实现图片广告轮换效果代码
2011/07/07 Javascript
JavaScript高级程序设计 读书笔记之九 本地对象Array
2012/02/27 Javascript
javascript屏蔽右键代码
2014/05/15 Javascript
jQuery+ajax实现无刷新级联菜单示例
2015/05/21 Javascript
js中javascript:void(0) 真正含义
2020/11/05 Javascript
js实现内容显示并使用json传输数据
2016/03/16 Javascript
写jQuery插件时的注意点
2017/02/20 Javascript
js 去掉字符串前后空格实现代码集合
2017/03/25 Javascript
JS按条件 serialize() 对应标签的使用方法
2017/07/24 Javascript
JS简单实现查看文档创建日期、修改日期和文档大小的方法示例
2018/04/08 Javascript
vue实现页面滚动到底部刷新
2019/08/16 Javascript
微信小程序学习总结(四)事件与冒泡实例分析
2020/06/04 Javascript
安装Python的web.py框架并从hello world开始编程
2015/04/25 Python
Django 返回json数据的实现示例
2020/03/05 Python
CSS3中的@keyframes关键帧动画的选择器绑定
2016/06/13 HTML / CSS
JINS眼镜官方网站:日本最大的眼镜邮购
2016/10/14 全球购物
电大学习个人自我评价范文
2013/10/04 职场文书
前台接待岗位职责
2013/12/03 职场文书
环境工程专业自荐信
2014/03/03 职场文书
二年级学生评语大全
2014/04/23 职场文书
三月学雷锋月活动总结
2014/04/28 职场文书
爱国演讲稿500字
2014/05/04 职场文书
公司合作意向书范文
2014/07/30 职场文书
医药销售自我评价200字
2014/09/11 职场文书
夫妻双方自愿离婚协议书
2014/10/24 职场文书
领导工作表现评语
2015/01/04 职场文书
Netty结合Protobuf进行编解码的方法
2021/06/26 Java/Android