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 相关文章推荐
showModelessDialog()使用详解
Sep 21 Javascript
javascript 写类方式之五
Jul 05 Javascript
node.js中的events.emitter.listeners方法使用说明
Dec 10 Javascript
Bootstrap每天必学之折叠
Apr 12 Javascript
浅析Javascript的自动分号插入(ASI)机制
Sep 29 Javascript
javascript循环链表之约瑟夫环的实现方法
Jan 16 Javascript
Javascript设计模式之装饰者模式详解篇
Jan 17 Javascript
详解用webpack把我们的业务模块分开打包的方法
Jul 20 Javascript
Vue中的组件及路由使用实例代码详解
May 22 Javascript
Vue组件实现触底判断
Jun 26 Javascript
javascript浅层克隆、深度克隆对比及实例解析
Feb 09 Javascript
Vue 中如何将函数作为 props 传递给组件的实现代码
May 12 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代码分析
2016/11/24 PHP
再论Javascript的类继承
2011/03/05 Javascript
读jQuery之二(两种扩展)
2011/06/11 Javascript
js变量以及其作用域详解
2020/07/18 Javascript
如何使用JS获取IE上传文件路径(IE7,8)
2013/07/08 Javascript
jquery提取元素里的纯文本不包含span等里的内容
2013/09/30 Javascript
JavaScript 实现鼠标拖动元素实例代码
2014/02/24 Javascript
Javascript正则控制文本框只能输入整数或浮点数
2014/09/02 Javascript
JavaScript中的值类型转换介绍
2014/12/31 Javascript
深入理解jquery跨域请求方法
2016/05/18 Javascript
AngularJS的Filter的示例详解
2017/03/07 Javascript
关于jQuery库冲突的完美解决办法
2017/05/20 jQuery
JQuery 封装 Ajax 常用方法(推荐)
2017/05/21 jQuery
响应式框架Bootstrap栅格系统的实例
2017/12/19 Javascript
Vue-component全局注册实例
2018/09/06 Javascript
策略模式实现 Vue 动态表单验证的方法
2019/09/16 Javascript
浅谈Three.js截图并下载的大坑
2019/11/01 Javascript
Nodejs环境实现socket通信过程解析
2020/07/03 NodeJs
寻找网站后台地址的python脚本
2014/09/01 Python
python条件变量之生产者与消费者操作实例分析
2017/03/22 Python
Python自定义线程池实现方法分析
2018/02/07 Python
解决安装tensorflow遇到无法卸载numpy 1.8.0rc1的问题
2018/06/13 Python
Python 列表去重去除空字符的例子
2019/07/20 Python
关于win10在tensorflow的安装及在pycharm中运行步骤详解
2020/03/16 Python
澳大利亚最大的百货公司:Myer
2018/12/21 全球购物
德国家用电器购物网站:Premiumshop24
2019/08/22 全球购物
英语自荐信常用语句
2013/12/13 职场文书
商业活动邀请函
2014/02/04 职场文书
四风问题查摆剖析材料
2014/10/11 职场文书
基层干部个人对照检查及整改措施
2014/10/28 职场文书
通报表扬范文
2015/01/17 职场文书
工作年限证明范本
2015/06/15 职场文书
课改心得体会范文
2016/01/25 职场文书
室外天线与收音机天线杆接合方法
2022/04/05 无线电
vue特效之翻牌动画
2022/04/20 Vue.js
html中相对位置与绝对位置的具体使用
2022/05/15 HTML / CSS