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 反科里化 this [译]
Sep 20 Javascript
jquery快捷动态绑定键盘事件的操作函数代码
Oct 17 Javascript
Jquery获取元素的父容器对象示例代码
Feb 10 Javascript
判断及设置浏览器全屏模式
Apr 20 Javascript
node.js中的querystring.parse方法使用说明
Dec 10 Javascript
jQuery实现鼠标划过展示大图的方法
Mar 09 Javascript
javascript禁止超链接跳转的方法
Feb 02 Javascript
jQuery EasyUI基础教程之EasyUI常用组件(推荐)
Jul 15 Javascript
详解js数组的完全随机排列算法
Dec 16 Javascript
vue的style绑定background-image的方式和其他变量数据的区别详解
Sep 03 Javascript
JavaScript中AOP的实现与应用
May 06 Javascript
vue项目部署到nginx/tomcat服务器的实现
Aug 26 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
解决phpmyadmin中文乱码问题。。。
2007/01/18 PHP
ThinkPHP中的三大自动简介
2014/08/22 PHP
php使用glob函数快速查询指定目录文件的方法
2014/11/15 PHP
php+iframe 实现上传文件功能示例
2020/03/04 PHP
JavaScript 类型的包装对象(Typed Wrappers)
2011/10/27 Javascript
跨域请求的完美解决方法(JSONP, CORS)
2016/06/12 Javascript
js对象浅拷贝和深拷贝详解
2016/09/05 Javascript
JavaScript数据结构之二叉树的计数算法示例
2017/04/13 Javascript
在微信小程序里使用watch和computed的方法
2018/08/02 Javascript
深入理解es6块级作用域的使用
2019/03/28 Javascript
vue 路由缓存 路由嵌套 路由守卫 监听物理返回操作
2020/08/06 Javascript
linux系统使用python监控apache服务器进程脚本分享
2014/01/15 Python
Python的面向对象编程方式学习笔记
2016/07/12 Python
python 实现删除文件或文件夹实例详解
2016/12/04 Python
pygame 精灵的行走及二段跳的实现方法(必看篇)
2017/07/10 Python
python2.6.6如何升级到python2.7.14
2018/04/08 Python
Django 使用Ajax进行前后台交互的示例讲解
2018/05/28 Python
Python redis操作实例分析【连接、管道、发布和订阅等】
2019/05/16 Python
基于Python安装pyecharts所遇的问题及解决方法
2019/08/12 Python
python爬虫-模拟微博登录功能
2019/09/12 Python
利用HTML5画出一个坦克的形状具体实现代码
2013/06/20 HTML / CSS
Pretty Little Thing爱尔兰:时尚女性服饰
2017/03/27 全球购物
KENZO官网:高田贤三在法国创立的品牌
2019/05/16 全球购物
有abstract方法的类一定要用abstract修饰吗
2016/03/14 面试题
旷课检讨书3000字
2014/02/04 职场文书
军训教官感言
2014/03/02 职场文书
晨会主持词
2014/03/17 职场文书
给妈妈洗脚活动方案
2014/08/16 职场文书
地方课程教学计划
2015/01/19 职场文书
小学教师个人工作总结2015
2015/04/20 职场文书
工程项目合作意向书
2015/05/08 职场文书
报案材料怎么写
2015/05/25 职场文书
参观监狱警示教育心得体会
2016/01/15 职场文书
小学四年级班务总结该怎么写?
2019/08/16 职场文书
Python通过m3u8文件下载合并ts视频的操作
2021/04/16 Python
MySQL新手入门进阶语句汇总
2022/09/23 MySQL