ref存储对象和reactive深度响应式递归地对对象的嵌套属性进行响应式处理

ref 不会递归地对 对象数组 中的每个属性或元素进行深度响应式处理。如果你需要递归处理嵌套属性,reactive 是更适合的选择。让我通过具体的例子来展示这一点。

例子:ref 存储对象和嵌套对象

1. 使用 ref 存储嵌套对象:
import { createApp, ref } from 'vue';

createApp({
  setup() {
    // 使用 ref 存储对象,包含嵌套属性
    const user = ref({
      name: 'Alice',
      profile: {
        age: 25,
        address: 'New York'
      }
    });

    // 修改嵌套属性
    function updateUser() {
      user.value.profile.age = 26; // 修改嵌套对象的属性
    }

    return {
      user, // 返回 user 对象给模板
      updateUser
    };
  }
}).mount('#app');
模板部分:
<div id="app">
  <p>Name: {{ user.value.name }}</p>
  <p>Age: {{ user.value.profile.age }}</p>
  <button @click="updateUser">Update Age</button>
</div>
问题:

在这个例子中,ref 用于存储一个 对象,对象内有一个嵌套的 profile 对象。user.value.profile.age 是嵌套属性,它应该是响应式的。但问题在于,ref 不会递归地对嵌套对象进行响应式处理user.value.profile 并不是深度响应式的,而是浅响应式的。

这意味着,当你修改 user.value.profile.age 时,Vue 不会自动更新视图,因为 profile 对象没有被 深度响应式化

解决方法:

如果我们希望 profile 对象的嵌套属性(如 ageaddress)也能触发视图更新,我们需要通过 reactive 来深度响应式化这个对象。

2. 使用 reactive 存储嵌套对象:
import { createApp, reactive } from 'vue';

createApp({
  setup() {
    // 使用 reactive 创建深度响应式对象
    const user = reactive({
      name: 'Alice',
      profile: {
        age: 25,
        address: 'New York'
      }
    });

    // 修改嵌套属性
    function updateUser() {
      user.profile.age = 26; // 修改嵌套对象的属性
    }

    return {
      user, // 返回 user 对象给模板
      updateUser
    };
  }
}).mount('#app');
模板部分:
<div id="app">
  <p>Name: {{ user.name }}</p>
  <p>Age: {{ user.profile.age }}</p>
  <button @click="updateUser">Update Age</button>
</div>
解释:
  • 在这个例子中,reactive 用来将 user 对象及其内部属性(如 profile)深度响应式化。
  • 现在,修改 user.profile.age 时,profile 对象age 属性 都是 深度响应式的,因此视图会自动更新。

总结:

  • ref 存储 对象数组 时,它只会 创建响应式引用不会递归地对对象的嵌套属性进行响应式处理。你需要使用 .value 来访问和修改对象的内容。如果对象有嵌套的属性,ref 无法保证它们是响应式的,除非显式地使用 reactive
  • reactive 会对 对象 及其所有 嵌套属性 进行深度响应式处理,无需使用 .value,并且修改嵌套属性时视图会自动更新。

何时使用 refreactive

  • ref 适用于 基本数据类型(如 numberstring)以及 简单的对象或数组,但你需要通过 .value 来访问和修改数据。
  • reactive 适用于 复杂数据类型(如 对象数组),并且会自动递归地将对象的每个属性都变成响应式。
### Vue 3 实现响应式对象的方法原理 #### 方法一:通过 `reactive` 函数创建响应式对象Vue 3 中,可以使用 Composition API 提供的 `reactive` 函数来创建一个响应式对象。这个函数接收一个普通 JavaScript 对象作为参数,并返回一个新的代理对象 (Proxy object),该对象具有追踪其内部属性的能力。 ```javascript import { reactive } from 'vue'; const state = reactive({ count: 0, }); console.log(state.count); // 输出: 0 state.count++; console.log(state.count); // 输出: 1 ``` 当访问或修改这些属性时,Vue 能够自动检测到变化并更新视图[^1]。 #### 方法二:通过 `ref` 创建基本类型的响应式变量 除了复杂的嵌套对象外,Vue 3 还提供了 `ref` 函数用于定义简单的原始值(如字符串、数字等)成为响应式的引用类型。它会返回一个带有 `.value` 属性的对象,允许开发者显式地获取或设置当前持有的值。 ```javascript import { ref, watchEffect } from 'vue'; let counter = ref(0); watchEffect(() => { console.log(`The current value of the counter is ${counter.value}`); }); // The current value of the counter is 0. counter.value += 1; // The current value of the counter is 1. ``` 每当 `counter.value` 发生改变时,依赖它的副作用函数就会重新执行,从而触发相应的 UI 更新逻辑[^2]。 #### 原理解析 Vue 3 的响应式系统主要基于 ES6 引入的语言特性——`Proxy` `Reflect` 构建而成。相比于 Vue 2 所使用的 `Object.defineProperty()` 方案,新的实现方式解决了许多旧版存在的局限性: - **全面覆盖属性变更**:不再局限于已知键名的操作监控,新增加或移除属性同样会被捕捉; - **数组变动感知**:不仅限于特定方法拦截,任何针对数组元素及其长度的变化都能被识别; - **简化深层监听开销**:无需再手动遍历子节点完成递归转换工作,整体效率更高且易于维护; - **增强用户体验**:去掉了诸如 `$set/$delete` 等特殊语法糖需求,使代码编写更为直观流畅[^4]。 综上所述,借助现代浏览器环境下的强大工具集,Vue 3 成功构建了一套既高效又易用的数据绑定框架,极大地方便了前端开发人员的工作流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值