Vue2.X和Vue3.0数据响应原理变化的区别

 更新时间:2019年11月07日 09:53:38   作者:Hector本尊  
这篇文章主要介绍了Vue2.X和Vue3.0数据响应原理变化的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

defineProperty 定义对象的属性,只不过属性里的get和set实现了响应式。

常用:

  • value属性值
  • get
  • set
  • writeable 是否可写
  • enumrable 可遍历

Vue从改变一个数据到发生改变的过程

 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);

结果显示:

 

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);

结果显示:

真正的私有变量

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • vue Element UI扩展内容过长使用tooltip显示

    vue Element UI扩展内容过长使用tooltip显示

    这篇文章主要为大家介绍了vue Element UI扩展内容过长使用tooltip展示鼠标hover时的提示信息,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • vue 遮罩和ref的使用setup版和非setup版

    vue 遮罩和ref的使用setup版和非setup版

    这篇文章主要介绍了vue 遮罩和ref的使用,setup版和非setup版,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • 老生常谈Vue中的侦听器watch

    老生常谈Vue中的侦听器watch

    开发中我们在data返回的对象中定义了数据,这个数据通过插值语法等方式绑定到template中,这篇文章主要介绍了Vue中的侦听器watch,需要的朋友可以参考下
    2022-10-10
  • 从零撸一个pc端vue的ui组件库( 计数器组件 )

    从零撸一个pc端vue的ui组件库( 计数器组件 )

    这篇文章主要介绍了pc端vue的ui组件库的实现方法,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • nuxt3中server routes的使用详解

    nuxt3中server routes的使用详解

    本文主要介绍了nuxt3中server routes的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05
  • avue实现自定义搜索栏及清空搜索事件的实践

    avue实现自定义搜索栏及清空搜索事件的实践

    本文主要介绍了avue实现自定义搜索栏及清空搜索事件的实践,主要包括对搜索栏进行自定义,并通过按钮实现折叠搜索栏效果,具有一定的参考价值,感兴趣的可以了解一下
    2021-12-12
  • 开发Vue树形组件的示例代码

    开发Vue树形组件的示例代码

    本篇文章主要介绍了开发Vue树形组件的示例代码,它展现了组件的递归使用。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • Vue中实现过渡动画效果实例详解

    Vue中实现过渡动画效果实例详解

    最近在写vue的一个项目要实现过渡的效果,虽然vue动画不是强项,库也多,但是基本的坑还是得踩扎实,下面这篇文章主要给大家介绍了关于Vue中实现过渡动画效果的相关资料,需要的朋友可以参考下
    2022-08-08
  • vue中keep-alive组件的入门使用教程

    vue中keep-alive组件的入门使用教程

    这篇文章主要给大家介绍了关于vue中keep-alive组件的入门使用教程,文中通过示例代码介绍的非常详细,对大家学习或者使用vue具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • element自定义表单验证上传身份证正反面的实现

    element自定义表单验证上传身份证正反面的实现

    表单验证在很多地方都可以用的到,本文主要介绍了element自定义表单验证上传身份证正反面的实现,文中根据实例编码详细介绍的十分详尽,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03

最新评论