Vue2.X和Vue3.0数据响应原理变化的区别


Posted in Javascript onNovember 07, 2019

defineProperty 定义对象的属性,只不过属性里的get和set实现了响应式。

常用:

  • value属性值
  • get
  • set
  • writeable 是否可写
  • enumrable 可遍历

Vue从改变一个数据到发生改变的过程

Vue2.X和Vue3.0数据响应原理变化的区别

 Vue2.X数据响应原理

创建页面,实现延时2s修改对象的值。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>LearnVue3.0</title>
</head>
<body>
  <div id="app"></div>
  <script type="text/javascript" src="test.js"></script>
  <script type="text/javascript">
    const vm = new vue();
    setTimeout(function () {
      console.log('change');
      console.log(vm.$data);
      vm.$data.a = 444;
    }, 2000);

  </script>
</body>
</html>

defineProperty 实现:

function vue() {
  this.$data = {
    a: 1
  };
  this.el = document.getElementById('app');
  this._html = "";
  this.observe(this.$data);
  this.render();
}

vue.prototype.observe = function (obj) {
  let self = this;
  let value;

  for (let key in obj) {
    value = obj[key];
    if (typeof value === 'object') {
      this.observe(value);
    } else {
      Object.defineProperty(this.$data, key, {
        get: function () {
          return value;
        },
        set: function (newvalue) {
          value = newvalue;
          self.render()
        }
      })
    }
  }
}

vue.prototype.render = function () {
  this._html = "I am " + this.$data.a;
  this.el.innerHTML = this._html;
}

在Chrome中console运行,结果页面显示: I am 444

针对数组特性化处理:

let arraypro = Array.prototype;
// 为什么要create再次创建对象,create是深拷贝,不影响之前的arraypro
let arrayob = Object.create(arraypro);
// 定义哪些方法触发更新
let arr = ["push", "pop", "shift"];

// arr里的方法,既能保持原有方法,又能触发更新
// 装饰者模式
arr.forEach(function (method, index) {
  // 对自己的push方法重写
  arrayob[method] = function () {
    let ret = arraypro[method].apply(this, arguments);
    // self.render();
    console.log('检测到数组变化,触发更新');
    return ret;
  }
});

在Chrome中console运行示例:

let arr = [];
arr.__proto__ = arrayob;
arr.push(1);

结果显示:

Vue2.X和Vue3.0数据响应原理变化的区别 

Vue3.0数据响应原理

Vue3.0数据响应原理

创建页面,实现延时2s修改对象的值。代码同上。

Proxy实现:

function vue() {
  this.$data = {
    a: 1
  };
  this.el = document.getElementById('app');
  this._html = "";
  this.observe(this.$data);
  this.render();
}

vue.prototype.observe = function (obj) {
  let self = this;

  this.$data = new Proxy(this.$data, {
    get: function (target, key) {
      return target[key];
    },
    set: function (target, key, newvalue) {
      target[key] = newvalue;
      self.render();
    }
  })
}

vue.prototype.render = function () {
  this._html = "I am " + this.$data.a;
  this.el.innerHTML = this._html;
}

在Chrome中console运行,结果页面显示: I am 444

为什么改用Proxy

  • defineProperty只能监听某个属性,不能对全对象监听
  • 可以省去for in循环提升效率
  • 可以监听数组,不用再去单独的对数组做特异性操作

Proxy还能做什么

校验类型

function createValidator(target, validator) {
  return new Proxy(target, {
    _validator: validator,
    set(target, key, value, proxy) {
      if(target.hasOwnProperty(key)) {
        let validator = this._validator[key];
        if(validator(value)) {
          return Reflect.set(target, key, value, proxy);
        } else {
          throw Error('type error');
        }
      }
    }
  })
}

let personValidator = {
  name(val) {
    return typeof val === 'string';
  },
  age(val) {
    return typeof val === 'number' && val > 18;
  }
}

class person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
    return createValidator(this, personValidator);
  }
}

在Chrome中console运行示例:

let tmp = new person('张三', 30);

结果显示:

Vue2.X和Vue3.0数据响应原理变化的区别

真正的私有变量

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery 倒计时效果实现秒杀思路
Sep 11 Javascript
jquery数据验证插件(自制,简单,练手)实例代码
Oct 24 Javascript
使用js声明数组,对象在jsp页面中(获得ajax得到json数据)
Nov 05 Javascript
jquery获取对象的方法足以应付常见的各种类型的对象
May 14 Javascript
jQuery 生成svg矢量二维码
Aug 09 Javascript
JS判断浏览器是否安装flash插件的简单方法
Sep 13 Javascript
深入对Vue.js $watch方法的理解
Mar 20 Javascript
Node.js编写CLI的实例详解
May 17 Javascript
js模拟百度模糊搜索的实例
Aug 04 Javascript
vue框架下部署上线后刷新报404问题的解决方案(推荐)
Apr 03 Javascript
浅谈Vuex注入Vue生命周期的过程
May 20 Javascript
vue实现点击按钮“查看详情”弹窗展示详情列表操作
Sep 09 Javascript
vue 实现v-for循环回来的数据动态绑定id
Nov 07 #Javascript
vue改变循环遍历后的数据实例
Nov 07 #Javascript
vue element-ui el-date-picker限制选择时间为当天之前的代码
Nov 07 #Javascript
vue v-for直接循环数字实例
Nov 07 #Javascript
jsonp格式前端发送和后台接受写法的代码详解
Nov 07 #Javascript
js实现数字从零慢慢增加到指定数字示例
Nov 07 #Javascript
详解Angular cli配置过程记录
Nov 07 #Javascript
You might like
destoon会员注册提示“数据校验失败(2)”解决方法
2014/06/21 PHP
PHP使用ffmpeg给视频增加字幕显示的方法
2015/03/12 PHP
jQuery Tab插件 用于在Tab中显示iframe,附源码和详细说明
2011/06/27 Javascript
Dom操作之兼容技巧分享
2011/09/20 Javascript
jQuery Ajax请求状态管理器打包
2012/05/03 Javascript
javascript自然分类法算法实现代码
2013/10/11 Javascript
jQuery 隐藏和显示 input 默认值示例
2014/06/03 Javascript
jQuery层级选择器用法分析
2015/02/10 Javascript
JQuery中基础过滤选择器用法实例分析
2015/05/18 Javascript
javascript实现超炫的向上滑行菜单实例
2015/08/03 Javascript
Bootstrap每天必学之导航组件
2016/04/25 Javascript
浅谈angularjs依赖服务注入写法的注意点
2017/04/24 Javascript
node.js 抓取代理ip实例代码
2017/04/30 Javascript
vue解决跨域路由冲突问题思路解析
2017/11/03 Javascript
微信小程序时间选择插件使用详解
2018/12/28 Javascript
如何用JavaScript实现功能齐全的单链表详解
2019/02/11 Javascript
Java Varargs 可变参数用法详解
2020/01/28 Javascript
[40:04]Secret vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.23
2019/09/05 DOTA
python实现自动登录人人网并访问最近来访者实例
2014/09/26 Python
Python 编码处理-str与Unicode的区别
2016/09/06 Python
python 保存float类型的小数的位数方法
2018/10/17 Python
Python基于matplotlib画箱体图检验异常值操作示例【附xls数据文件下载】
2019/01/07 Python
Pandas_cum累积计算和rolling滚动计算的用法详解
2019/07/04 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
python中如何进行连乘计算
2020/05/28 Python
opencv-python的RGB与BGR互转方式
2020/06/02 Python
Python docutils文档编译过程方法解析
2020/06/23 Python
详解pycharm2020.1.1专业版安装指南(推荐)
2020/08/07 Python
Python加载数据的5种不同方式(收藏)
2020/11/13 Python
CSS3打造百度贴吧的3D翻牌效果示例
2017/01/04 HTML / CSS
html5使用canvas绘制太阳系效果
2014/12/15 HTML / CSS
乌克兰电子和家用电器商店:Foxtrot
2019/07/23 全球购物
英国排名第一的餐具品牌:Denby Pottery
2019/11/01 全球购物
Web Service面试题:如何搭建Axis2的开发环境
2012/06/20 面试题
上海某公司.net方向笔试题
2014/09/14 面试题
云冈石窟导游词
2015/02/04 职场文书