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 instanceof 内部机制探析
Oct 15 Javascript
JavaScript NaN和Infinity特殊值 [译]
Sep 20 Javascript
jquery实现简单合拢与展开网页面板的方法
Sep 01 Javascript
原生JavaScript制作微博发布面板效果
Mar 11 Javascript
基于JavaScript实现购物网站商品放大镜效果
Sep 06 Javascript
详解vue-router2.0动态路由获取参数
Jun 14 Javascript
微信小程序录音与播放录音功能
Dec 25 Javascript
详解微信小程序与内嵌网页交互实现支付功能
Oct 22 Javascript
JavaScript创建对象的四种常用模式实例分析
Jan 11 Javascript
layui使用数据表格实现购物车功能
Jul 26 Javascript
vue+element树组件 实现树懒加载的过程详解
Oct 21 Javascript
three.js欧拉角和四元数的使用方法
Jul 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
无数据库的详细域名查询程序PHP版(1)
2006/10/09 PHP
让你同时上传 1000 个文件 (二)
2006/10/09 PHP
介绍几个array库的新函数 php
2006/12/29 PHP
通过jQuery打造支持汉字,拼音,英文快速定位查询的超级select插件
2010/06/18 Javascript
基于jQuery中对数组进行操作的方法
2013/04/16 Javascript
javascript中的括号()用法小结
2014/04/14 Javascript
js获取鼠标点击的位置实现思路及代码
2014/05/09 Javascript
Javascript学习指南
2014/12/01 Javascript
jQuery中 attr() 方法使用小结
2015/05/03 Javascript
详解JS正则replace的使用方法
2016/03/06 Javascript
jquery实用技巧之输入框提示语句
2016/07/28 Javascript
修改jquery中dialog的title属性方法(推荐)
2016/08/26 Javascript
webpack配置sass模块的加载的方法
2017/07/30 Javascript
简单实现js上传文件功能
2017/08/21 Javascript
详解vue项目中使用token的身份验证的简单实践
2019/03/08 Javascript
vue中重定向redirect:‘/index‘,不显示问题、跳转出错的完美解决
2020/09/28 Javascript
[36:33]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第二场 11.29
2020/12/02 DOTA
使用Python对MySQL数据操作
2017/04/06 Python
使用Django启动命令行及执行脚本的方法
2018/05/29 Python
Python小游戏之300行代码实现俄罗斯方块
2019/01/04 Python
PyTorch的深度学习入门教程之构建神经网络
2019/06/27 Python
详解python中*号的用法
2019/10/21 Python
Idea安装python显示无SDK问题解决方案
2020/08/12 Python
python模拟点击玩游戏的实例讲解
2020/11/26 Python
CSS实现聊天气泡效果
2020/04/26 HTML / CSS
HTML5 Canvas绘制文本及图片的基础教程
2016/03/14 HTML / CSS
html5 application cache遇到的严重问题
2012/12/26 HTML / CSS
HTML5中Localstorage的使用教程
2015/07/09 HTML / CSS
医药营销个人求职信
2014/04/12 职场文书
小学生推普周国旗下讲话稿
2014/09/21 职场文书
习总书记三严三实学习心得体会
2014/10/13 职场文书
社区学习党的群众路线教育实践活动心得体会
2014/11/03 职场文书
忠犬八公的故事观后感
2015/06/05 职场文书
人民的好儿女观后感
2015/06/18 职场文书
Pytorch DataLoader shuffle验证方式
2021/06/02 Python
基于redis+lua进行限流的方法
2022/07/23 Redis