💡 你是否遇到过这样的场景:一个嵌套对象,只想让它的第一层属性不可更改,但又不影响子级的响应式?
那么恭喜你,今天要介绍的shallowReadonly
就是你的“神兵利器”!🔥
🧠 什么是 shallowReadonly
?
在 Vue3 中,我们常用 readonly
来创建一个只读的响应式对象。但是它会递归地冻结整个对象树,包括所有嵌套的属性。
而 shallowReadonly
是它的“轻量版”:
- 只冻结对象的第一层属性
- 不会深度冻结嵌套对象
- 适用于性能优化和特定业务场景
📦 使用场景举例(真实项目中常见)
想象一下你在做一个后台管理系统,有一个用户信息对象:
const userInfo = {
id: 1,
name: 'Tom',
address: {
city: 'Beijing',
street: 'Haidian'
}
}
你想确保 id
和 name
不被修改,但允许 address.city
或 address.street
被动态更新。
这时候,使用 readonly(userInfo)
就太狠了,会导致 address
也无法修改!
✅ 正确做法:使用 shallowReadonly(userInfo)
🔍 实战代码解析
✅ 安装环境(Composition API)
npm install vue@next
然后在组件中引入:
import { shallowReadonly, isReadonly } from 'vue'
🧪 示例代码:
<script setup>
import { shallowReadonly, isReadonly } from 'vue'
const user = {
id: 1,
name: 'Jerry',
info: {
age: 25,
hobby: 'coding'
}
}
// 创建浅只读对象
const readonlyUser = shallowReadonly(user)
// 修改第一层属性 ❌ 报错!
try {
readonlyUser.name = 'Tom' // 无法修改
} catch (e) {
console.error('不能修改第一层属性:', e.message)
}
// 修改第二层属性 ✅ 成功
readonlyUser.info.age = 30
console.log(readonlyUser.info.age) // 输出 30
// 判断是否为只读
console.log(isReadonly(readonlyUser)) // true
console.log(isReadonly(readonlyUser.info)) // false(info 对象本身不是只读)
</script>
🚀 为什么选择 shallowReadonly
?
方法 | 是否可修改顶层属性 | 是否冻结嵌套属性 | 是否响应式 |
---|---|---|---|
reactive() | ✅ 可以 | ✅ 全部可变 | ✅ 是 |
readonly() | ❌ 不可以 | ❌ 所有都不可以 | ❌ 否 |
shallowReadonly() | ❌ 不可以 | ✅ 可以 | ✅ 是 |
📌 适合用于那些:
- 数据结构复杂
- 只想保护第一层不被误改
- 希望保留子属性的响应性或可变性
🧩 高级用法:结合 ref
/ reactive
使用
import { reactive, shallowReadonly } from 'vue'
export default {
setup() {
const state = reactive({
settings: {
theme: 'dark',
notifications: true
},
version: 'v1.0.0'
})
const protectedState = shallowReadonly(state)
return { protectedState }
}
}
此时你可以放心绑定到模板上,防止直接修改 settings
或 version
,但还能自由修改 settings.theme
!
🎁 小贴士 & 注意事项
shallowReadonly
只作用于对象的第一层属性。- 如果你希望某个嵌套对象也只读,需要手动再调用一次。
- 与
shallowReactive
类似,都是“浅处理”的响应式控制方式。 - 在大型系统中合理使用,可以有效避免数据污染和提高性能。
📌 总结
方法 | 特点 |
---|---|
readonly() | 全部只读,递归冻结,适合静态配置 |
shallowReadonly() | 仅第一层只读,子级仍可变,适合复杂结构保护关键字段 |
🎯 一句话总结:
shallowReadonly
是 Vue3 中一种非常实用、灵活的响应式控制方法,特别适合在大型项目中对复杂对象进行精细化管理!
💬 如果你觉得这篇文章对你有帮助,欢迎点赞 + 收藏 ❤️
📖 更多 Vue3 干货内容请关注我,持续输出前端高阶技巧!