浅谈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开发之三数组对象实例介绍
Nov 12 Javascript
什么是json和jsonp,jQuery json实例详详细说明
Dec 11 Javascript
JS打印gridview实现原理及代码
Feb 05 Javascript
JavaScript实现获取dom中class的方法
Feb 09 Javascript
很全面的JavaScript常用功能汇总集合
Jan 22 Javascript
js实现简单的计算器功能
Jan 16 Javascript
微信JS-SDK选取手机照片上传功能
Apr 21 Javascript
jquery 一键复制到剪切板的实例
Sep 20 jQuery
仿vue-cli搭建属于自己的脚手架的方法步骤
Apr 17 Javascript
js实现数据导出为EXCEL(支持大量数据导出)
Mar 31 Javascript
解决Nuxt使用axios跨域问题
Jul 06 Javascript
通过实例解析javascript Date对象属性及方法
Nov 04 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树的代码,可以嵌套任意层
2006/10/09 PHP
php将时间差转换为字符串提示
2011/09/07 PHP
PHP逐行输出(ob_flush与flush的组合)
2012/02/04 PHP
php中time()与$_SERVER[REQUEST_TIME]用法区别
2014/11/19 PHP
帝国cms目录结构分享
2015/07/06 PHP
利用PHP抓取百度阅读的方法示例
2016/12/18 PHP
php使用PDO执行SQL语句的方法分析
2017/02/16 PHP
Lumen timezone 时区设置方法(慢了8个小时)
2018/01/20 PHP
JS获取页面窗口大小的代码解读
2011/12/01 Javascript
基于JavaScript创建动态Dom
2015/12/08 Javascript
jquery插件jquery.confirm弹出确认消息
2015/12/22 Javascript
JavaScript知识点总结(四)之逻辑OR运算符详解
2016/05/31 Javascript
fullpage.js全屏滚动插件使用实例
2016/09/06 Javascript
Bootstrap选项卡学习笔记分享
2017/02/13 Javascript
js判断传入时间和当前时间大小实例(超简单)
2018/01/11 Javascript
用Fundebug插件记录网络请求异常的方法
2019/02/21 Javascript
浅析vue中的nextTick
2020/12/28 Vue.js
Python随机函数random()使用方法小结
2018/04/29 Python
使用python实现mqtt的发布和订阅
2019/05/05 Python
利用python在大量数据文件下删除某一行的例子
2019/08/21 Python
在Python中获取操作系统的进程信息
2019/08/27 Python
Django自带的加密算法及加密模块详解
2019/12/03 Python
Python3交互式shell ipython3安装及使用详解
2020/07/11 Python
Python局部变量与全局变量区别原理解析
2020/07/14 Python
HTML5 canvas实现雪花飘落特效
2016/03/08 HTML / CSS
使用纯HTML5编写一款网页上的时钟的代码分享
2015/11/16 HTML / CSS
美国网上鞋子零售商:Dr. Scholl’s Shoes
2017/11/17 全球购物
苹果Mac升级:MacSales.com
2017/11/20 全球购物
印度尼西亚电子产品购物网站:Kliknklik
2018/06/05 全球购物
初一学生评语大全
2014/04/24 职场文书
2014党员自我评议表范文
2014/09/20 职场文书
政风行风整改报告
2014/11/06 职场文书
民主评议党员个人自我评价
2015/03/03 职场文书
会计试用期工作总结2015
2015/05/28 职场文书
不知如何爱孩子,这些方法教会您
2019/08/06 职场文书
使用Ajax实现进度条的绘制
2022/04/07 Javascript