vue2数据响应式原理——数据劫持(初始篇)

简介: vue2数据响应式原理——数据劫持(初始篇)

在这里插入图片描述

前言

写这系列博客之前,还是想感慨一下尤大大的精明厉害之处。

vue的发展大家有目共睹,这一切离不开vue数据响应式的发明,尽管vue2的数据响应式处理还有一些问题,但这些问题都在vue3中进行了解决,那我为什么还要写vue2的数据响应式原理,而不直接写vue3的数据响应式原理呢?

因为vue2vue的发展中是个里程碑的存在,它的一些原理和思想对之后的vue发展奠定了基础,不管之后vue怎么变化,这些原理也不会变,这就是本篇博文中书写vue2数据响应式原理的原因。

开始之前先附上尤大大的总结:在getter中收集依赖,在setter中触发依赖。

开始研究前先创建 index.htmlindex.js两个文件,在 index.html文件中引入 index.js文件,之后我们将在 index.js文件中书写代码,运行 index.html文件查看效果。

本文完整代码仓库地址: Vue2 Responsive principle(建议初学者跟着代码来学)

一个完整的响应式应该包括:

  • 数据劫持
  • 收集依赖
  • 发布订阅

本系列查阅顺序:

  1. [vue2数据响应式原理——数据劫持(初始篇)]
  2. [vue2数据响应式原理——数据劫持(对象篇)]
  3. [vue2数据响应式原理——数据劫持(数组篇)]
  4. [vue2数据响应式原理——依赖收集和发布订阅]

数据劫持(初始篇)

为什么需要数据劫持?vue中当我们对一个响应式数据进行更改时我们需要监听到这个响应式数据的变化,这就需要用到Object.defineProperty()或者ES6Proxy来对数据的更改操作进行劫持,之后进行一些操作后将数据更改的结果反馈给用户,这就实现了简单的响应式数据,vue2使用的是Object.defineProperty()所以我们这里只讲Object.defineProperty()

Object.defineProperty()

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

语法:

Object.defineProperty(obj, prop, descriptor)

参数:

  • obj

要定义属性的对象。

  • prop

要定义或修改的属性的名称或 Symbol 。

  • descriptor

要定义或修改的属性描述符。

先看一个小实例:

let obj = {};
Object.defineProperty(obj, "a", {
    value: 3,
});
Object.defineProperty(obj, "b", {
    value: "我是obj的b",
});
console.log(obj.a);
console.log(obj.b);

打印结果:
在这里插入图片描述
这里我们定义了一个obj的空对象,然后利用Object.defineProperty()obj中添加了a、b两个属性,之后我们在访问obj.aobj.b时就能打印出结果。

因为obj本身是个空对象,所以这里Object.defineProperty()通过在obj对象上定义a、b新属性时就实现了数据劫持,将我们处理的a、b反馈给了用户。

看到这里大家应该已经明白Object.defineProperty()的基本作用以及数据劫持的原理了。

但是这个时候大家可能会有一个问题,为什么要用Object.defineProperty()obj新增属性而不直接在定义obj时定义好属性呢?

因为在使用Object.defineProperty()时我们可以对新增的属性添加一些特别的功能:

configurable

  • 当且仅当该属性的 configurable 键值为 true 时,该属性的描述符才能够被改变,同时该属性也能从对应的对象上被删除。

默认为 false。

enumerable

  • 当且仅当该属性的 enumerable 键值为 true 时,该属性才会出现在对象的枚举属性中。

默认为 false。
数据描述符还具有以下可选键值:

value

  • 该属性对应的值。可以是任何有效的 JavaScript 值(数值,对象,函数等)。

默认为 undefined。

writable

  • 当且仅当该属性的 writable 键值为 true 时,属性的值,也就是上面的 value,才能被赋值运算符 (en-US)改变。

默认为 false。
存取描述符还具有以下可选键值:

get

  • 属性的 getter 函数,如果没有 getter,则为 undefined。当访问该属性时,会调用此函数。执行时不传入任何参数,但是会传入 this 对象(由于继承关系,这里的this并不一定是定义该属性的对象)。该函数的返回值会被用作属性的值。

默认为 undefined。

set

  • 属性的 setter 函数,如果没有 setter,则为 undefined。当属性值被修改时,会调用此函数。该方法接受一个参数(也就是被赋予的新值),会传入赋值时的 this 对象。

默认为 undefined。

例如:上面那个代码的例子我们试着修改a属性:

let obj = {};
Object.defineProperty(obj, "a", {
    value: 3,

});
console.log(obj.a);
obj.a = 9;
console.log(obj.a);

在这里插入图片描述
可以看到a并没有被修改,这就是因为writable配置默认为false,我们修改一下writable配置:

let obj = {};
Object.defineProperty(obj, "a", {
    value: 3,
    //是否可写:是否可更改
    writable: true,
});
console.log(obj.a);
obj.a = 9;
console.log(obj.a);

在这里插入图片描述
可以看到a可以被修改了,这就是使用Object.defineProperty()来定义obj对象属性的原因:为了能够对新增的这个属性进行一些配置。

相关文章
|
7月前
|
JavaScript 前端开发 开发者
响应式原理:Vue 如何跟踪数据变化
【4月更文挑战第22天】Vue 的响应式系统是其核心,通过数据双向绑定实现视图与数据同步。依赖收集和观测数据使Vue能跟踪变化,变化通知组件更新视图。高效的更新策略如批量更新和虚拟DOM提升性能。组件化和可组合性支持有效通信和代码复用,强调数据驱动开发。开发者应合理组织数据、谨慎处理变更并充分利用组件化优势,以提高效率和用户体验。
120 2
|
2月前
|
存储
Vue2响应式原理模拟
【10月更文挑战第17天】在实际应用中,Vue2 使用了更高效和复杂的技术来实现响应式,但这种模拟为我们提供了一个起点,让我们能够逐步深入地探究响应式原理的奥秘。你可以根据自己的需求和理解,进一步扩展和完善这个模拟,以更好地掌握 Vue2 的响应式机制。
31 2
|
9天前
|
JavaScript 前端开发 开发者
Vue是如何劫持响应式对象的
Vue是如何劫持响应式对象的
17 1
|
12天前
|
监控 JavaScript 算法
深度剖析 Vue.js 响应式原理:从数据劫持到视图更新的全流程详解
本文深入解析Vue.js的响应式机制,从数据劫持到视图更新的全过程,详细讲解了其实现原理和运作流程。
|
2月前
|
JavaScript 前端开发 算法
前端优化之超大数组更新:深入分析Vue/React/Svelte的更新渲染策略
本文对比了 Vue、React 和 Svelte 在数组渲染方面的实现方式和优缺点,探讨了它们与直接操作 DOM 的差异及 Web Components 的实现方式。Vue 通过响应式系统自动管理数据变化,React 利用虚拟 DOM 和 `diffing` 算法优化更新,Svelte 通过编译时优化提升性能。文章还介绍了数组更新的优化策略,如使用 `key`、分片渲染、虚拟滚动等,帮助开发者在处理大型数组时提升性能。总结指出,选择合适的框架应根据项目复杂度和性能需求来决定。
|
5月前
|
JavaScript API
Vue数据动态代理机制的实现以及响应式与数据劫持
Vue数据动态代理机制的实现以及响应式与数据劫持
45 0
|
JavaScript 前端开发
76Vue - 响应式原理(如何追踪变化)
76Vue - 响应式原理(如何追踪变化)
39 0
|
JavaScript 算法 前端开发
Vue.js 2.0源码透析: 数据绑定与渲染机制的实现方式
Vue.js 2.0源码透析: 数据绑定与渲染机制的实现方式
81 0
|
7月前
|
JavaScript 前端开发
解释 Vue 的响应式系统原理。
解释 Vue 的响应式系统原理。
92 0
|
7月前
|
JavaScript 前端开发 API
【Vue】响应式与数据劫持
【Vue】响应式与数据劫持
91 0