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 相关文章推荐
UI Events 用户界面事件
Jun 27 Javascript
简述JavaScript提交表单的方式 (Using JavaScript Submit Form)
Mar 18 Javascript
AngularJS的Filter的示例详解
Mar 07 Javascript
详解Angular 4.x NgTemplateOutlet
May 24 Javascript
Vue Transition实现类原生组件跳转过渡动画的示例
Aug 19 Javascript
浅谈vue项目打包优化策略
Sep 29 Javascript
详解vue组件中使用路由方法
Feb 12 Javascript
微信小程序 select 下拉框组件功能
Sep 09 Javascript
JS实现简单日历特效
Jan 03 Javascript
微信小程序实现下滑到底部自动翻页功能
Mar 07 Javascript
Jquery+AJAX实现无刷新上传并重命名文件操作示例【PHP后台接收】
May 29 jQuery
微信小程序动态评分展示/五角星展示/半颗星展示/自定义长度展示功能的实现
Jul 22 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获取linux命令结果的实例
2017/03/13 PHP
浅谈laravel aliases别名的原理
2019/10/24 PHP
javascript实现上传图片前的预览(TX的面试题)
2007/08/20 Javascript
window.location和document.location的区别分析
2008/12/23 Javascript
HTML Dom与Css控制方法
2010/10/25 Javascript
js限制文本框输入长度两种限制方式(长度、字节数)
2012/12/19 Javascript
jQuery筛选器children()案例详解(图文)
2013/02/17 Javascript
有关于JS构造函数的重载和工厂方法
2013/04/07 Javascript
jQuery中append()方法用法实例
2014/12/25 Javascript
基于JS2Image实现圣诞树代码
2015/12/24 Javascript
浅析JS操作DOM的一些常用方法
2016/05/13 Javascript
Vue.js每天必学之表单控件绑定
2016/09/05 Javascript
基于chosen插件实现人员选择树搜索自动筛选功能
2016/09/24 Javascript
总结js函数相关知识点
2018/02/27 Javascript
使用JavaScript实现node.js中的path.join方法
2018/08/12 Javascript
详解关于webpack多入口热加载很慢的原因
2019/04/24 Javascript
微信小程序纯文本实现@功能
2020/04/08 Javascript
[02:19]DOTA2上海特级锦标赛 观赛指南 Spectator Guide
2016/02/04 DOTA
python查找第k小元素代码分享
2013/12/18 Python
Django实现快速分页的方法实例
2017/10/22 Python
python 多个参数不为空校验方法
2019/02/14 Python
python实现维吉尼亚算法
2019/03/20 Python
Python3 sys.argv[ ]用法详解
2019/10/24 Python
python使用正则来处理各种匹配问题
2019/12/22 Python
python Paramiko使用示例
2020/09/21 Python
python+flask编写一个简单的登录接口
2020/11/13 Python
python3中celery异步框架简单使用+守护进程方式启动
2021/01/20 Python
Huda Beauty官方商店:化妆和美容产品
2020/09/05 全球购物
初二生物教学反思
2014/02/03 职场文书
教师节促销活动方案
2014/02/14 职场文书
《美丽的公鸡》教学反思
2014/02/25 职场文书
大学生实习鉴定评语
2014/04/25 职场文书
2014年幼儿园老师工作总结
2014/12/05 职场文书
苏州园林导游词
2015/02/03 职场文书
毕业欢送会致辞
2015/07/29 职场文书
python编写五子棋游戏
2021/05/25 Python