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中的数学函数
Apr 04 Javascript
用js一次改变多个input的readonly属性值的方法
Jun 11 Javascript
JS中实现简单Formatter函数示例代码
Aug 19 Javascript
javascript密码强度校验代码(两种方法)
Aug 10 Javascript
jQuery结合CSS制作动态的下拉菜单
Oct 27 Javascript
js倒计时简单实现方法
Dec 17 Javascript
第四篇Bootstrap网格系统偏移列和嵌套列
Jun 21 Javascript
使用smartupload组件实现jsp+jdbc上传下载文件实例解析
Jan 05 Javascript
解决vue-cli + webpack 新建项目出错的问题
Mar 20 Javascript
详解解决Vue相同路由参数不同不会刷新的问题
Oct 12 Javascript
浅谈webpack+react多页面开发终极架构
Nov 11 Javascript
JS在Array数组中按指定位置删除或添加元素对象方法示例
Nov 19 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数组中包含中文的排序方法
2014/06/03 PHP
Laravel框架下载,安装及路由操作图文详解
2019/12/04 PHP
js 禁用浏览器的后退功能的简单方法
2008/12/10 Javascript
引用外部js乱码问题分析及解决方案
2013/04/12 Javascript
利用cookie记住背景颜色示例代码
2013/11/04 Javascript
jquery实现TAB选项卡鼠标经过带延迟效果的方法
2015/07/27 Javascript
javascript中Date format(js日期格式化)方法小结
2015/12/17 Javascript
Bootstrap媒体对象的实现
2016/05/01 Javascript
BootStrap 动态添加验证项和取消验证项的实现方法
2016/09/28 Javascript
JS实现淡入淡出图片效果的方法分析
2016/12/20 Javascript
5种JavaScript脚本加载的方式
2017/01/16 Javascript
js读取json文件片段中的数据实例
2017/03/09 Javascript
利用jQuery实现一个简单的表格上下翻页效果
2017/03/14 Javascript
vue表单绑定实现多选框和下拉列表的实例
2017/08/12 Javascript
Vue仿手机qq的实例代码(demo)
2017/09/08 Javascript
JavaScript使用Math.random()生成简单的验证码
2019/01/21 Javascript
react结合bootstrap实现评论功能
2020/05/30 Javascript
详细介绍Python语言中的按位运算符
2013/11/26 Python
python网络编程示例(客户端与服务端)
2014/04/24 Python
python安装与使用redis的方法
2016/04/19 Python
python实现八大排序算法(2)
2017/09/14 Python
python实现守护进程、守护线程、守护非守护并行
2018/05/05 Python
python groupby 函数 as_index详解
2019/12/16 Python
关于python3.9安装wordcloud出错的问题及解决办法
2020/11/02 Python
python爬虫爬取淘宝商品比价(附淘宝反爬虫机制解决小办法)
2020/12/03 Python
amazeui页面分析之登录页面的示例代码
2020/08/25 HTML / CSS
欧洲最大的美妆零售网站:Feelunique
2017/01/14 全球购物
编辑找工作求职信分享
2014/01/03 职场文书
高一新生军训感言
2014/03/02 职场文书
二年级评语大全
2014/04/23 职场文书
任命书模板
2014/06/04 职场文书
幼儿教师师德师风演讲稿
2014/08/22 职场文书
mysql 8.0.24版本安装配置方法图文教程
2021/05/12 MySQL
如何在Python中妥善使用进度条详解
2022/04/05 Python
Java 多态分析
2022/04/26 Java/Android
win10+RTX3050ti+TensorFlow+cudn+cudnn配置深度学习环境的方法
2022/06/25 Servers