Vue: ref、reactive、shallowRef、shallowReactive

1. ref

作用 :创建响应式数据引用(支持基本类型和对象)。
原理

  • 通过 value 属性访问/修改数据

  • 对象类型内部自动转换为 reactive

  • 使用 Object.defineProperty 实现响应式

API

TypeScript 复制代码
import { ref } from 'vue'

const count = ref(0) // 基本类型
const user = ref({ name: 'Alice' }) // 对象类型自动转为 reactive

// 修改值
count.value++ 
user.value.name = 'Bob'

模板中使用

TypeScript 复制代码
<template>
  <div>{{ count }}</div>
  <button @click="count++">Increment</button>
</template>

2. reactive

作用 :创建深层响应式对象(仅支持对象/数组)。
原理

  • 基于 Proxy 实现深度响应式

  • 嵌套对象自动转为 reactive

  • 直接访问属性(无需 .value)

API

TypeScript 复制代码
import { reactive } from 'vue'

const state = reactive({
  count: 0,
  user: { name: 'Alice' } // 嵌套对象自动响应式
})

// 修改值
state.count++
state.user.name = 'Bob'

模板中使用

html 复制代码
<template>
  <div>{{ state.count }}</div>
  <button @click="state.count++">Increment</button>
</template>

3. shallowRef

作用 :创建浅层响应式引用(仅顶层 value 响应)。
原理

  • 只追踪 .value 变化(不追踪内部属性)

  • 对象内部修改 不会 触发更新

  • 替换整个 .value 触发更新

API

TypeScript 复制代码
import { shallowRef } from 'vue'

const user = shallowRef({ name: 'Alice' })

//  ❌ 内部修改无效(不会触发更新)
user.value.name = 'Bob'

// ✅ 替换整个对象有效(触发更新)
user.value = { name: 'Bob' }

典型场景

  • 大型不可变数据(如三方库实例)

  • 性能敏感场景避免深度监听

4. shallowReactive

作用 :创建浅层响应式对象(仅顶层属性响应)。
原理

  • 只响应顶层属性变化

  • 嵌套对象 不会 自动转为响应式

API

TypeScript 复制代码
import { shallowReactive } from 'vue'

const state = shallowReactive({
  count: 0,
  user: { name: 'Alice' } // 嵌套对象非响应式
})

// ✅ 顶层修改有效
state.count++ 

// ❌ 嵌套修改无效(不会触发更新)
state.user.name = 'Bob'

典型场景

  • 表单分组(只关心组变化)

  • 性能优化(避免深度监听大对象)

总结对比表

特性 ref reactive shallowRef shallowReactive
支持类型 所有类型 对象/数组 所有类型 对象/数组
深层响应式 ✅ (对象自动转)
响应触发条件 .value 变化 属性修改 .value 替换 顶层属性修改
访问方式 需要 .value 直接访问 需要 .value 直接访问
性能开销 中等 较高(深度监听)
典型场景 基本类型/对象引用 复杂状态对象 大型不可变数据 层级明确的数据

代码示例总结

TypeScript 复制代码
<script setup>
import { ref, reactive, shallowRef, shallowReactive } from 'vue'

// 1. ref(深度响应)
const deepRef = ref({ count: 0 })
deepRef.value.count++ // 触发更新

// 2. reactive(深度响应)
const deepReactive = reactive({ user: { name: 'Alice' } })
deepReactive.user.name = 'Bob' // 触发更新

// 3. shallowRef(浅层响应)
const shallow = shallowRef({ count: 0 })
shallow.value.count++ //  ❌ 不触发更新
shallow.value = { count: 1 } // ✅ 触发更新

// 4. shallowReactive(浅层响应)
const shallowState = shallowReactive({ 
  user: { name: 'Alice' } 
})
shallowState.user.name = 'Bob' //  ❌ 不触发更新
shallowState.user = { name: 'Bob' } // ✅ 触发更新
</script>

选择建议

  • ref 处理基本类型或需要整体替换的对象

  • reactive 处理深度嵌套的复杂状态

  • shallowXXX 优化大型数据或明确不需要深度监听的场景

相关推荐
TinssonTai11 小时前
这个 VS Code 插件让我的 AI Coding 又快又稳 - 旧瓶装新酒
前端·人工智能·程序员
体验家11 小时前
体验家 XMPlus 网页端问卷 SDK 技术解析:用几行 JavaScript 实现精准场景触发与防打扰机制
开发语言·前端·javascript
VidDown11 小时前
VidDown 工具站:视频分辨率技术
javascript·网络·编辑器·音视频·视频编解码·视频
Maimai1080812 小时前
Web3 前端交易系统如何落地:从下单 UI 到 Operation 编码、签名与实时状态更新
前端·react.js·ui·架构·前端框架·web3
kidding72312 小时前
高效备忘清单工具类小程序
前端·计算机网络·微信小程序·小程序
IMPYLH12 小时前
HTML 的 <abbr> 元素
前端·算法·html
小鹿软件办公12 小时前
倒计时开启:Chromium 宣布几周内将全面切断 MV2 扩展支持
开发语言·javascript·ublock origin
李白的天不白12 小时前
Tree-Shaking
前端
Csvn13 小时前
TypeScript:你以为安全的 `JSON.parse` 其实是颗雷 — 运行时类型安全实战
前端·javascript
触底反弹13 小时前
从 JS 引擎执行原理理解数据类型:栈内存、堆内存与作用域
javascript·数据结构·面试