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 相关文章推荐
javascript 处理HTML元素必须避免使用的一种方法
Jul 30 Javascript
LazyLoad 延迟加载(按需加载)
May 31 Javascript
JS中window.open全屏命令解析及使用示例
Dec 11 Javascript
快速学习jQuery插件 Cookie插件使用方法
Dec 01 Javascript
javascript中的作用域和闭包详解
Jan 13 Javascript
Bootstrap导航条可点击和鼠标悬停显示下拉菜单的实现代码
Jun 23 Javascript
JavaScript条件判断_动力节点Java学院整理
Jun 26 Javascript
vue.js实现备忘录功能的方法
Jul 10 Javascript
使用vue构建移动应用实战代码
Aug 02 Javascript
JS实现点击拉拽轮播图pc端移动端适配
Sep 05 Javascript
vue动态子组件的两种实现方式
Sep 01 Javascript
浅谈TypeScript的类型保护机制
Feb 23 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程序员的技术瓶颈分析
2011/07/17 PHP
PHP封装的数据库保存session功能类
2016/07/11 PHP
PHP基于方差和标准差计算学生成绩的稳定性示例
2017/07/04 PHP
PHP数组内存利用率低和弱类型详细解读
2017/08/10 PHP
项目实践之javascript技巧
2007/12/06 Javascript
javascript中的new使用
2010/03/20 Javascript
面向切面编程(AOP)的理解
2015/05/01 Javascript
JavaScript基于setTimeout实现计数的方法
2015/05/08 Javascript
编写高性能Javascript代码的N条建议
2015/10/12 Javascript
举例讲解JavaScript中关于对象操作的相关知识
2015/11/16 Javascript
vue.js学习笔记:如何加载本地json文件
2017/01/17 Javascript
js实现网页的两个input标签内的数值加减(示例代码)
2017/08/15 Javascript
在小程序开发中使用npm的方法
2018/10/17 Javascript
vue组件实践之可搜索下拉框功能
2018/11/25 Javascript
jQuery访问json文件中数据的方法示例
2019/01/28 jQuery
vue中$refs, $emit, $on, $once, $off的使用详解
2019/05/26 Javascript
js实现随机抽奖
2020/03/19 Javascript
基于JS实现计算24点算法代码实例解析
2020/07/23 Javascript
[34:41]夜魇凡尔赛茶话会 第二期02:你画我猜
2021/03/11 DOTA
使用python绘制人人网好友关系图示例
2014/04/01 Python
python连接MySQL数据库实例分析
2015/05/12 Python
Python实现HTTP协议下的文件下载方法总结
2016/04/20 Python
Python操作使用MySQL数据库的实例代码
2017/05/25 Python
Scrapy框架使用的基本知识
2018/10/21 Python
Python中实现单例模式的n种方式和原理
2018/11/14 Python
Python openpyxl 遍历所有sheet 查找特定字符串的方法
2018/12/10 Python
简单了解python装饰器原理及使用方法
2019/12/18 Python
Python参数传递及收集机制原理解析
2020/06/05 Python
浅析NumPy 切片和索引
2020/09/02 Python
详解python使用金山词霸的翻译功能(调试工具断点的使用)
2021/01/07 Python
美国瑜伽服装和装备购物网站:Mukha Yoga
2019/02/22 全球购物
教师党的群众路线教育实践活动个人整改方案
2014/10/31 职场文书
2015年学校政教处工作总结
2015/05/26 职场文书
2016年度先进班组事迹材料
2016/03/01 职场文书
java Nio使用NioSocket客户端与服务端交互实现方式
2021/06/15 Java/Android
德生BCL3000抢先使用感受和评价
2022/04/07 无线电