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 相关文章推荐
js form action动态修改方法
Nov 04 Javascript
JavaScript 克隆数组最简单的方法
Feb 12 Javascript
JavaScript 获取任一float型小数点后两位的小数
Jun 30 Javascript
浅析JavaScript动画
Jun 10 Javascript
jquery实现选中单选按钮下拉伸缩效果
Aug 06 Javascript
学习JavaScript设计模式(链式调用)
Nov 26 Javascript
整理Javascript基础语法学习笔记
Nov 29 Javascript
百度多文件异步上传控件webuploader基本用法解析
Nov 07 Javascript
Bootstrap提示框效果的实例代码
Jul 12 Javascript
JS实现常见的查找、排序、去重算法示例
May 21 Javascript
vue-auto-focus: 控制自动聚焦行为的 vue 指令方法
Aug 25 Javascript
Selenium执行Javascript脚本参数及返回值过程详解
Apr 01 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
分页详解 从此分页无忧(PHP+mysql)
2007/11/23 PHP
php使用substr()和strpos()联合查找字符串中某一特定字符的方法
2015/05/12 PHP
$.ajax返回的JSON无法执行success的解决方法
2011/09/09 Javascript
jquery trigger伪造a标签的click事件取代window.open方法
2014/06/23 Javascript
jQuery+JSON实现AJAX二级联动实例分析
2015/12/18 Javascript
举例讲解如何判断JavaScript中对象的类型
2016/04/22 Javascript
JAVA Web实时消息后台服务器推送技术---GoEasy
2016/11/04 Javascript
javascript学习之json入门
2016/12/22 Javascript
jQuery表格(Table)基本操作实例分析
2017/03/10 Javascript
JS实现新建文件夹功能
2017/06/17 Javascript
javascript 玩转Date对象(实例讲解)
2017/07/11 Javascript
基于JavaScript 性能优化技巧心得(分享)
2017/12/11 Javascript
vue学习教程之带你一步步详细解析vue-cli
2017/12/26 Javascript
vue better scroll 无法滚动的解决方法
2018/06/07 Javascript
详解.vue文件解析的实现
2018/06/11 Javascript
通过函数作用域和块级作用域看javascript的作用域链
2018/08/05 Javascript
Vuex的actions属性的具体使用
2019/04/14 Javascript
vue 使用高德地图vue-amap组件过程解析
2019/09/07 Javascript
VUEX 数据持久化,刷新后重新获取的例子
2019/11/12 Javascript
简单了解JS打开url的方法
2020/02/21 Javascript
es6中let和const的使用方法详解
2020/02/24 Javascript
js实现3D旋转相册
2020/08/02 Javascript
python实现爬虫统计学校BBS男女比例之数据处理(三)
2015/12/31 Python
python制作爬虫并将抓取结果保存到excel中
2016/04/06 Python
实例探究Python以并发方式编写高性能端口扫描器的方法
2016/06/14 Python
Python3 jupyter notebook 服务器搭建过程
2018/11/30 Python
使用PyQt4 设置TextEdit背景的方法
2019/06/14 Python
Tensorflow训练MNIST手写数字识别模型
2020/02/13 Python
Python环境配置实现pip加速过程解析
2020/11/27 Python
利用html5 file api读取本地文件示例(如图片、PDF等)
2018/03/07 HTML / CSS
详解HTML5 录音的踩坑之旅
2017/12/26 HTML / CSS
亚马逊加拿大网站:Amazon.ca
2020/01/06 全球购物
社区健康教育实施方案
2014/03/18 职场文书
2014教师党员自我评议(5篇)
2014/09/20 职场文书
房产电话营销开场白
2015/05/29 职场文书
导游词之桂林山水
2019/09/20 职场文书