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 相关文章推荐
extjs 的权限问题 要求控制的对象是 菜单,按钮,URL
Mar 09 Javascript
探讨js字符串数组拼接的性能问题
Oct 11 Javascript
JS实现可直接显示网页代码运行效果的HTML代码预览功能实例
Aug 06 Javascript
JS实现可展开折叠层的鼠标拖曳效果
Oct 09 Javascript
Bootstrap轮播加上css3动画,炫酷到底!
Dec 22 Javascript
深入理解ES6 Promise 扩展always方法
Sep 26 Javascript
如何去除vue项目中的#及其ie9兼容性
Jan 11 Javascript
jQuery实现图片上传预览效果功能完整实例【测试可用】
May 28 jQuery
node.js使用express框架进行文件上传详解
Mar 03 Javascript
基于vue-cli3创建libs库的实现方法
Dec 04 Javascript
JS原型和原型链原理与用法实例详解
Feb 05 Javascript
js实现网页版贪吃蛇游戏
Feb 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
老照片 - 几十年前的收音机与人
2021/03/02 无线电
一个经典的PHP文件上传类分享
2014/11/18 PHP
php自定义函数实现二维数组排序功能
2016/07/20 PHP
jQuery 表单验证插件formValidation实现个性化错误提示
2009/06/23 Javascript
jQuery与ExtJS之选择实例分析
2010/08/19 Javascript
JavaScript 创建运动框架的实现代码
2013/05/08 Javascript
js获取控件位置以及不同浏览器中的差别介绍
2013/08/08 Javascript
jQuery中:eq()选择器用法实例
2014/12/29 Javascript
JavaScript将Web页面内容导出到Word及Excel的方法
2015/02/13 Javascript
js数组去重的5种算法实现
2015/11/04 Javascript
javascript实现省市区三级联动下拉框菜单
2015/11/17 Javascript
z-blog SyntaxHighlighter 长代码无法换行解决办法(基于jquery)
2015/11/18 Javascript
javascript仿京东导航左侧分类导航下拉菜单效果
2020/11/25 Javascript
jQuery侧边栏实现代码
2016/05/06 Javascript
jQuery弹出遮罩层效果完整示例
2016/09/13 Javascript
javascript实现复选框全选或反选
2017/02/04 Javascript
详解如何在 vue 项目里正确地引用 jquery 和 jquery-ui的插件
2017/06/01 jQuery
angular4 如何在全局设置路由跳转动画的方法
2017/08/30 Javascript
基于zTree树形菜单的使用实例
2017/12/25 Javascript
angularjs结合html5实现拖拽功能
2018/06/25 Javascript
详解如何给React-Router添加路由页面切换时的过渡动画
2019/04/25 Javascript
vue项目使用.env文件配置全局环境变量的方法
2019/10/24 Javascript
Node.js创建一个Express服务的方法详解
2020/01/06 Javascript
详解JavaScript中的链式调用
2020/11/27 Javascript
理解生产者消费者模型及在Python编程中的运用实例
2016/06/26 Python
python 矩阵增加一行或一列的实例
2018/04/04 Python
和孩子一起学习python之变量命名规则
2018/05/27 Python
Python列表(list)所有元素的同一操作解析
2019/08/01 Python
python语音识别指南终极版(有这一篇足矣)
2020/09/09 Python
萨克斯第五大道精品百货店: Saks Fifth Avenue
2017/04/28 全球购物
Yummie官方网站:塑身衣和衣柜必需品
2019/10/29 全球购物
Discard Protocol抛弃协议的作用是什么
2015/10/10 面试题
优秀毕业生推荐信
2013/11/02 职场文书
庆八一活动方案
2014/01/25 职场文书
介绍信应该怎么开?
2019/04/03 职场文书
python入门学习关于for else的特殊特性讲解
2021/11/20 Python