Vue 数据绑定的原理分析


Posted in Javascript onNovember 16, 2020

原理

其实原理很简单,就是拦截了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', '');

以上就是Vue 数据绑定的原理分析的详细内容,更多关于Vue 数据绑定的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
jquery实现点击label的同时触发文本框点击事件的方法
Jun 05 Javascript
js精美的幻灯片画集特效代码分享
Aug 29 Javascript
AngularJS 执行流程详细介绍
Aug 18 Javascript
使用BootStrap实现悬浮窗口的效果
Dec 13 Javascript
Vue中的数据监听和数据交互案例解析
Jul 12 Javascript
three.js实现3D模型展示的示例代码
Dec 31 Javascript
jQuery实现滚动到底部时自动加载更多的方法示例
Feb 18 jQuery
jquery UI实现autocomplete在获取焦点时得到显示列表功能示例
Jun 04 jQuery
使用js在layui中实现上传图片压缩
Jun 18 Javascript
javascript实现动态时钟的启动和停止
Jul 29 Javascript
微信小程序仿淘宝热搜词在搜索框中轮播功能
Jan 21 Javascript
vue实现一个矩形标记区域(rectangle marker)的方法
Oct 28 Javascript
Vue 使用iframe引用html页面实现vue和html页面方法的调用操作
Nov 16 #Javascript
Vue指令实现OutClick的示例
Nov 16 #Javascript
浅谈vue在html中出现{{}}的原因及解决方式
Nov 16 #Javascript
vue组件中传值EventBus的使用及注意事项说明
Nov 16 #Javascript
小程序自定义弹框效果
Nov 16 #Javascript
vuex中遇到的坑,vuex数据改变,组件中页面不渲染操作
Nov 16 #Javascript
基于Vue+Webpack拆分路由文件实现管理
Nov 16 #Javascript
You might like
php中 $$str 中 &quot;$$&quot; 的详解
2015/07/06 PHP
PHP版本的选择5.2.17 5.3.27 5.3.28 5.4 5.5兼容性问题分析
2016/04/04 PHP
在CentOS系统上从零开始搭建WordPress博客的全流程记录
2016/04/21 PHP
自写的利用PDO对mysql数据库增删改查操作类
2018/02/19 PHP
点击按钮或链接不跳转只刷新页面的脚本整理
2013/10/22 Javascript
jquery ajax应用中iframe自适应高度问题解决方法
2014/04/12 Javascript
js onmousewheel事件多次触发问题解决方法
2014/10/17 Javascript
nodejs开发环境配置与使用
2014/11/17 NodeJs
node.js中的favicon.ico请求问题处理
2014/12/15 Javascript
JavaScript学习笔记之定时器
2015/01/22 Javascript
JavaScript中的await/async的作用和用法
2016/10/31 Javascript
浅谈vue引用静态资源需要注意的事项
2018/09/28 Javascript
JavaScript实现的拼图算法分析
2019/02/13 Javascript
vue自定义指令实现仅支持输入数字和浮点型的示例
2019/10/30 Javascript
在vue项目中 实现定义全局变量 全局函数操作
2020/10/26 Javascript
[58:15]2018DOTA2亚洲邀请赛 4.1 小组赛 A组 NB vs Liquid
2018/04/02 DOTA
跟老齐学Python之变量和参数
2014/10/10 Python
启动Atom并运行python文件的步骤
2018/11/09 Python
python如何实现视频转代码视频
2019/06/17 Python
python内存监控工具memory_profiler和guppy的用法详解
2019/07/29 Python
python元组和字典的内建函数实例详解
2019/10/22 Python
TensorFlow实现自定义Op方式
2020/02/04 Python
用CSS3实现Win8风格的方格导航菜单效果
2013/04/10 HTML / CSS
CSS3 实现倒计时效果
2020/11/25 HTML / CSS
欧洲最古老的鞋厂:Peter Kaiser
2019/11/05 全球购物
关于Java finally的面试题
2016/04/27 面试题
公司年会演讲稿范文
2014/01/11 职场文书
记帐员岗位责任制
2014/02/08 职场文书
热爱祖国的演讲稿
2014/05/04 职场文书
信息员培训方案
2014/06/12 职场文书
高中教师先进事迹材料
2014/08/22 职场文书
2014年宣传工作总结
2014/11/18 职场文书
网络营销计划书
2015/01/17 职场文书
2016年度员工工作表现评语
2015/12/02 职场文书
先进基层党组织事迹材料2016
2016/02/29 职场文书
Python趣味挑战之教你用pygame画进度条
2021/05/31 Python