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 相关文章推荐
javascript下过滤数组重复值的代码
Sep 10 Javascript
js函数的引用, 关于内存的开销
Sep 17 Javascript
JQuery选择器、过滤器大整理
May 26 Javascript
js数组常见操作及数组与字符串相互转化实例详解
Nov 10 Javascript
JavaScript函数基础详解
Feb 03 Javascript
详解weex默认webpack.config.js改造
Jan 08 Javascript
微信小程序实现图片预览功能
Jan 31 Javascript
React中嵌套组件与被嵌套组件的通信过程
Jul 11 Javascript
Node.js搭建WEB服务器的示例代码
Aug 15 Javascript
基于Vue 服务端Cookies删除的问题
Sep 21 Javascript
vue-cli项目使用mock数据的方法(借助express)
Apr 15 Javascript
Vue学习之组件用法实例详解
Jan 06 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
暴雪前总裁遗憾:没尽早追赶Dota 取消星际争霸幽灵
2020/03/08 星际争霸
PHP 的ArrayAccess接口 像数组一样来访问你的PHP对象
2010/10/12 PHP
浅谈php serialize()与unserialize()的用法
2013/06/05 PHP
yii添删改查实例
2015/11/16 PHP
PHP中-&gt;和=&gt;的含义及使用示例解析
2020/08/06 PHP
javascript 模式设计之工厂模式详细说明
2010/05/10 Javascript
js实现翻页后保持checkbox选中状态的实现方法
2012/11/03 Javascript
Javascript连接多个数组不用concat来解决
2014/03/24 Javascript
js获取页面传来参数的方法
2014/09/06 Javascript
jQuery插件cxSelect多级联动下拉菜单实例解析
2016/06/24 Javascript
AngularJs bootstrap详解及示例代码
2016/09/01 Javascript
基于vue+canvas的excel-like组件实例详解
2017/11/28 Javascript
jQuery EasyUI 选项卡面板tabs的使用实例讲解
2017/12/25 jQuery
Angular5给组件本身的标签添加样式class的方法
2018/04/07 Javascript
详解基于Vue2.0实现的移动端弹窗(Alert, Confirm, Toast)组件
2018/08/02 Javascript
详解easyui 切换主题皮肤
2019/04/04 Javascript
Vue.js 中的实用工具方法【推荐】
2019/07/04 Javascript
[02:31]2014DOTA2国际邀请赛2009专访:干爹表现出乎意料 看好DK杀回决赛
2014/07/20 DOTA
[01:31:03]DOTA2完美盛典全回顾 见证十五项大奖花落谁家
2017/11/28 DOTA
go和python调用其它程序并得到程序输出
2014/02/10 Python
Python实现获取域名所用服务器的真实IP
2015/10/25 Python
Python实现图片尺寸缩放脚本
2018/03/10 Python
对python中dict和json的区别详解
2018/12/18 Python
在Python中如何传递任意数量的实参的示例代码
2019/03/21 Python
基于css3实现漂亮便签样式
2013/03/18 HTML / CSS
CSS3解析抖音LOGO制作的方法步骤
2019/04/11 HTML / CSS
瑞士领先的网上超市:LeShop.ch
2018/11/14 全球购物
Python里面如何拷贝一个对象
2014/02/17 面试题
销售类个人求职信范文
2013/09/25 职场文书
个人简历自我评价八例
2013/10/31 职场文书
公益活动策划方案
2014/01/09 职场文书
小学音乐教学反思
2014/02/05 职场文书
放飞梦想演讲稿
2014/05/05 职场文书
品牌服务方案
2014/06/03 职场文书
暑假生活随笔
2015/08/15 职场文书
Python中三种花式打印的示例详解
2022/03/19 Python