shallowReactive,shallowReadonly,toRaw()和markRaw()详解

在 Vue 3 的响应式系统中,shallowReactiveshallowReadonlytoRaw 和 markRaw 是用于精细化控制响应性和数据行为的高级 API。它们适用于需要对响应式对象进行更细粒度管理的场景。


🧩 一、shallowReactive

✅ 作用:

创建一个 浅层响应式对象,仅对对象的第一层属性进行响应式转换,不会递归处理嵌套对象。

示例:

import { shallowReactive } from 'vue'

const state = shallowReactive({
  user: {
    name: 'Alice',
    profile: {
      age: 25
    }
  }
})

// 修改第一层属性是响应式的
state.user = { name: 'Bob' }

// 修改嵌套属性不是响应式的 ❌
state.user.profile.age++

⚠️ 此时 profile.age 的变化不会触发视图更新。


🔒 二、shallowReadonly

✅ 作用:

创建一个 浅只读对象,其自身属性不可更改,但嵌套对象不会被深度冻结。

示例:

import { shallowReadonly } from 'vue'

const config = shallowReadonly({
  theme: 'dark',
  settings: {
    fontSize: 14,
    layout: 'sidebar'
  }
})

config.theme = 'light' // ❌ 报错:不能修改只读属性

config.settings.fontSize = 16 // ✅ 成功:settings 是普通对象,未被深度冻结

📦 三、toRaw

✅ 作用:

获取一个响应式或只读对象的原始对象(即去除响应式包装)。

使用场景:

  • 当你需要将响应式对象传给第三方库时(如 JSON.stringify、axios 请求等)
  • 避免 Vue 对对象进行不必要的追踪

示例:

import { reactive, toRaw } from 'vue'

const state = reactive({ count: 0 })
const rawState = toRaw(state)

console.log(rawState === state) // false
console.log(rawState.count) // 0

⚠️ toRaw 可以穿透 reactivereadonlyshallowReactive 等包装。


🚫 四、markRaw

✅ 作用:

标记一个对象,使其永远不会被转为响应式。即使你把它传给 reactive() 或作为响应式对象的属性。

使用场景:

  • 将大型对象、第三方库实例排除在响应式系统之外
  • 提升性能,避免不必要的代理创建

示例:

import { markRaw, reactive } from 'vue'

class User {
  constructor(name) {
    this.name = name
  }
}

const user = markRaw(new User('Alice'))

const state = reactive({ user })

console.log(state.user === user) // true
console.log(isReactive(state)) // true
console.log(isReactive(state.user)) // false

✅ user 被标记为 raw,即使放入响应式对象中也不会被代理。


📊 对比总结表

API响应式层级是否可写是否解包嵌套对象典型用途
reactive()深层响应式✅ 可写✅ 自动解包默认首选
shallowReactive()浅层响应式✅ 可写❌ 不解包性能优化
readonly()深层只读❌ 不可写✅ 自动解包数据保护
shallowReadonly()浅层只读❌ 不可写❌ 不解包控制只读范围
toRaw()获取原始对象--获取非响应式副本
markRaw()排除响应式--第三方对象、性能优化

💡 最佳实践建议

场景推荐使用
默认状态管理reactive() / ref()
大型对象/频繁局部更新shallowReactive() + trigger()
只想冻结顶层属性shallowReadonly()
需要原始对象toRaw()
排除某些对象进入响应式系统markRaw()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值