Vue响应式数据的原理

简介: Vue响应式数据的原理

在 vue2 的响应式中,存在着添加属性、删除属性、以及通过下标修改数组,但页面不会自动更新的问题。而这些问题在 vue3 中都得以解决。

vue3 采用了 proxy 代理,用于拦截对象中任意属性的变化,包括:属性的读写、属性的添加、属性的删除、以及通过下标修改数组,都可以自动更新页面。

proxy 代理:用于在目标对象之前架设一层拦截,外界对该对象的访问,都必须先通过这层拦截,因此可以对外界的访问进行过滤和改写。

另外 vue3 还采用了 reflect 反射,用于对源对象的属性进行操作。

reflect 反射:是一个 JS 的内置对象,它提供了一系列的方法,这些方法和对象中的功能相对应。经常配合 proxy 使用。proxy 用于拦截,reflect 用于操作。

Proxy 代理的使用【代理对象】:

// 假设这个是我们创建的 reactive 数据
const data = {
  name: "张三",
  age: 21
};
// 创建 proxy 代理 data 对象,添加到 vue 的实例对象中
// 语法:const vm = new Proxy(要代理的数据, 配置对象)
const vm = new Proxy(data, {
  // 当有人读取 vm 的某个属性时调用
  get(target, propName) {
  // target 就是被代理的这个对象,propName 就是当前操作的属性
    console.log(`有人读取了vm身上的${propName}属性`);
    return target[propName]; // 返回代理对象中的这个属性
  },
  // 当有人修改 vm 的某个属性时,或给 vm 添加某个属性时调用
  set(target, propName, value) {
  // value 就是修改的值
    console.log(`有人修改了vm身上的${propName}属性,我要去更新页面了!`);
    return (target[index] = value); // 修改或添加这个属性
  },
  // 当有人删除 vm 的某个属性时调用
  deleteProperty(target, propName) {
    console.log(`有人删除了vm身上的${propName}属性,我要去更新页面了!`);
    return delete target[propName]; // 删除代理对象中的这个属性
  },
});

:proxy 不仅能检测到读取属性和修改属性,还能检测到添加属性和删除属性。所以在 vue3 中添加或删除一个对象中的属性时,页面也会自动更新。

:读取时触发 get 函数、修改或添加时触发 set 函数、删除时触发 deleteProperty 函数。

Proxy 代理的使用【代理数组】:

// 假设这个是我们创建的 reactive 数据
const arr = ["张三", "李四", "王五"];
// 创建 proxy 代理 arr 数组,添加到 vue 的实例对象中
// 语法:const app = new Proxy(要代理的数据, 配置对象)
const app = new Proxy(arr, {
  // 当有人读取 app 的某个值时调用
  get(target, index) {
    // target 就是被代理的这个数组,index 就是当前操作的属性或下标
    console.log(`有人读取了app身上下标${index}的值`);
    return target[index]; // 返回代理数组中的这个值
  },
  // 当有人修改 app 的某个值时,或给 app 添加一个值时调用
  set(target, index, value) {
    // value 就是修改的值
    console.log(`有人修改了app身上下标${index}的值,我要去更新页面了!`);
    return (target[index] = value); // 修改或添加代理数组中的这个值
  },
  // 当有人删除 app 的某个值时调用
  deleteProperty(target, index) {
    console.log(`有人删除了app身上下标${index}的值,我要去更新页面了!`);
    return delete target[index]; // 删除代理数组中的这个值
  },
});

:proxy 支持通过下标操作数组,例如查看数据、修改数据、增加数据。所以在 vue3 中通过下标修改数组时,页面也会自动更新。

:在使用 push 等方法的时候,length 属性也会发生变化。所以 vue3 分别判断了 push、pop、unshift、shift 等方法,用于区分拦截的各种情况。

Proxy 代理的使用【深层数据的问题】

const data = {
  name: "张三",
  age: 20,
  arr: ["a", "b", "c"],
  obj: { q: 1, w: 2 },
};
const app = new Proxy(data, {
  get(target, propName) {
    console.log(`有人读取了app身上的${propName}属性`);
    return target[propName];
  },
  set(target, propName, value) {
    console.log(`有人修改了app身上的${propName}属性,我要去更新页面了!`);
    return (target[propName] = value);
  },
  deleteProperty(target, propName) {
    console.log(`有人删除了app身上的${propName}属性,我要去更新页面了!`);
    return delete target[propName];
  },
});

:proxy 代理深层数据的时候,只会触发 get 函数,并不会触发 set 函数

:proxy 只会拦截第一层数据,所以 vue3 对深层数据进行了循环遍历,重新利用 proxy 代理了深层数据。

原创作者:吴小糖

创作时间:2023.8.12

相关文章
|
2月前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
165 64
|
2月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
102 17
|
2月前
|
JavaScript 前端开发 API
介绍一下Vue中的响应式原理
介绍一下Vue中的响应式原理
45 1
|
2月前
|
监控 JavaScript 算法
深度剖析 Vue.js 响应式原理:从数据劫持到视图更新的全流程详解
本文深入解析Vue.js的响应式机制,从数据劫持到视图更新的全过程,详细讲解了其实现原理和运作流程。
|
2月前
|
JavaScript
Vue 双向数据绑定原理
Vue的双向数据绑定通过其核心的响应式系统实现,主要由Observer、Compiler和Watcher三个部分组成。Observer负责观察数据对象的所有属性,将其转换为getter和setter;Compiler解析模板指令,初始化视图并订阅数据变化;Watcher作为连接Observer和Compiler的桥梁,当数据变化时触发相应的更新操作。这种机制确保了数据模型与视图之间的自动同步。
|
2月前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
71 1
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
1070 0
|
22天前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
119 1
|
1天前
|
JavaScript 安全 API
iframe嵌入页面实现免登录思路(以vue为例)
通过上述步骤,可以在Vue.js项目中通过 `iframe`实现不同应用间的免登录功能。利用Token传递和消息传递机制,可以确保安全、高效地在主应用和子应用间共享登录状态。这种方法在实际项目中具有广泛的应用前景,能够显著提升用户体验。
22 8
|
2天前
|
存储 设计模式 JavaScript
Vue 组件化开发:构建高质量应用的核心
本文深入探讨了 Vue.js 组件化开发的核心概念与最佳实践。
16 1