当前位置: 首页 > news >正文

Reactive与Ref的故事

Vue 3的两位"响应式英雄":Reactive与Ref的故事

基本介绍:响应式的两种武器

Vue 3提供了两种创建响应式数据的主要API:reactive()ref()。它们像两种不同的魔法工具,各有所长,共同构建Vue的响应式王国。

┌─────────────────────────────────────────────────────────┐
│                  Vue 3 响应式API对比                    │
├───────────────────┬─────────────────┬───────────────────┤
│      特性         │    reactive     │       ref         │
├───────────────────┼─────────────────┼───────────────────┤
│ 适用数据类型      │ 对象类型        │ 任何类型          │
├───────────────────┼─────────────────┼───────────────────┤
│ 访问/修改方式     │ 直接属性访问    │ .value属性        │
├───────────────────┼─────────────────┼───────────────────┤
│ 内部实现          │ Proxy           │ 包装对象+Proxy    │
├───────────────────┼─────────────────┼───────────────────┤
│ 解构后保持响应性  │     ❌          │      ✅           │
└───────────────────┴─────────────────┴───────────────────┘

生活类比:魔法容器与魔法盒子

🏰 想象一个奇幻世界的故事:

  • reactive()是一座"魔法城堡"

    • 城堡里的每个房间都被施了魔法(对象的每个属性都是响应式的)
    • 你可以直接进入任何房间(直接访问对象属性)
    • 但是,如果你试图把房间拆下来带走(解构属性),魔法就会消失
    • 只有完整的建筑物才能保持魔法(整个对象才有响应性)
  • ref()是一个"魔法盒子"

    • 盒子可以装任何东西(原始值或对象)
    • 必须打开盒子才能看到里面的东西(通过.value访问)
    • 盒子本身带着魔法标记,无论放在哪里都能被追踪(引用传递保持响应性)
    • 即使从大包裹中取出来(从对象解构),盒子仍然保持魔法效果

1. Reactive:对象的响应式转换器

reactive()将一个普通对象转换为响应式对象,使用ES6的Proxy实现深层响应式,适用于复杂数据结构。

实现流程

┌──────────────────────┐
│  调用reactive(obj)   │
└──────────┬───────────┘│▼
┌──────────────────────┐          ┌───────────────────┐
│ 检查obj是否为对象    │──否──────▶│ 返回原始值        │
└──────────┬───────────┘          └───────────────────┘│是▼
┌──────────────────────┐          ┌───────────────────┐
│ 检查缓存中是否已存在 │──是──────▶│ 返回现有响应式对象 │
└──────────┬───────────┘          └───────────────────┘│否▼
┌──────────────────────┐
│ 创建Proxy包装对象    │
└──────────┬───────────┘│▼
┌──────────────────────┐
│处理getter/setter拦截 │
└──────────┬───────────┘│▼
┌──────────────────────┐
│在getter中收集依赖    │
└──────────┬───────────┘│▼
┌──────────────────────┐
│在setter中触发更新    │
└──────────┬───────────┘│▼
┌──────────────────────┐
│ 返回Proxy对象        │
└──────────────────────┘

代码示例

import { reactive, watchEffect } from 'vue'// 创建响应式对象
const user = reactive({name: '张三',age: 30,address: {city: '北京',district: '朝阳区'}
})// 直接访问和修改
console.log(user.name) // 输出: 张三
user.age = 31 // 直接修改,会触发更新// 监听响应式变化
watchEffect(() => {console.log(`${user.name}今年${user.age}岁,住在${user.address.city}`)
})// 深层嵌套属性也是响应式的
user.address.city = '上海' // 会触发上面的watchEffect重新执行// 🚫 解构后会失去响应性
const { name, age } = user
console.log(name) // 张三
// 修改解构出的变量不会触发更新
age = 32 // watchEffect不会重新执行

2. Ref:任意值的响应式包装器

ref()可以将任何类型的值(包括原始类型)包装成响应式对象,通过.value访问和修改内部值,在模板中会自动解包。

实现流程

┌──────────────────────┐
│    调用ref(value)    │
└──────────┬───────────┘│▼
┌──────────────────────┐
│  创建RefImpl对象     │
└──────────┬───────────┘│▼
┌──────────────────────┐
│内部维护_value属性    │
└──────────┬───────────┘│▼
┌──────────────────────┐        ┌───────────────────────┐
│value是对象吗?        │──是───▶│将value转换为reactive   │
└──────────┬───────────┘        └───────────────────────┘│否▼
┌──────────────────────┐
│定义value的getter/    │
│setter进行依赖收集    │
└──────────┬───────────┘│▼
┌──────────────────────┐
│返回包含.value的对象  │
└──────────────────────┘

代码示例

import { ref, watchEffect } from 'vue'// 创建基本类型的响应式引用
const count = ref(0)
const message = ref('Hello')
const isActive = ref(true)// 必须通过.value访问和修改
console.log(count.value) // 输出: 0
count.value++ // 通过.value修改// 对象类型也可以使用ref
const user 

相关文章:

  • day22-数据结构之 栈队列
  • RAGFlow升级到最新0.18.0新手指南
  • APIfox参数化配置
  • AI 赋能 Copula 建模:大语言模型驱动的相关性分析革新
  • 操作系统-锁/内存/中断/IO
  • c++20引入的三路比较操作符<=>
  • 保姆教程-----安装MySQL全过程
  • DiT中的 Adaptive Layer Normalization (adaLN) 讲解
  • 【Android构建系统】如何在Camera Hal的Android.bp中选择性引用某个模块
  • 使用哈希表封装myunordered_set和myunordered_map
  • leetcode:58. 最后一个单词的长度(python3解法)
  • Centos7 中 Docker运行配置Apache
  • 【Shell的基本操作】
  • 第九天——贪心算法——非递减数组
  • Promise.all 详解
  • ch10 题目参考思路
  • 突围“百机大战”,云轴科技ZStack智塔获IDC中国AI大模型一体机推荐品牌
  • 文章记单词 | 第87篇(六级)
  • Android App CAN通信测试
  • elementUI源码学习
  • 国际金价下跌,中概股多数上涨,穆迪下调美国主权信用评级
  • 淄博一酒店房间内被曝发现摄像头,当地警方已立案调查
  • 九江宜春领导干部任前公示,3人拟提名为县(市、区)长候选人
  • 龚正会见哥伦比亚总统佩特罗
  • 证监会:2024年依法从严查办证券期货违法案件739件,作出处罚决定592件、同比增10%
  • 今年有望投产里程已近3000公里,高铁冲刺谁在“狂飙”?