computed 默认返回只读 ref,.value 不可赋值但依赖数据仍可变;“只读”仅拦截计算结果写入,不锁死源头;需用 readonly 包裹源对象才能真正防篡改;支持写入须显式定义 set 函数。

computed 默认返回的是一个只读的 ref,意思是这个 ref 的 .value 不能被直接赋新值,但它的底层依赖数据依然可变——“只读”只作用于计算属性这一层,不锁死源头。
为什么说“只读”是表面的?
computed 创建的 ref 内部用 readonly 包裹,所以执行类似 myComputed.value = 'xxx' 会立即报错:Cannot assign to read only property。但这只是拦截了对计算结果本身的写入,不影响它所依赖的响应式源:
- 比如
const fullName = computed(() => user.name),你不能改fullName.value - 但只要拿到
user(比如从reactive或ref暴露出去),仍可改user.name,fullName就会随之更新
只读 ≠ 数据安全,真正防篡改得靠 readonly
如果要把计算结果“安全传递”给子组件或组合式函数,防止接收方意外修改源头,不能只靠 computed 自带的只读性。必须显式用 readonly 包裹整个响应式对象:
-
const safeUser = readonly(user)→ 连safeUser.name = 'xxx'都会失败 - 在组合式函数中,推荐统一返回
readonly(computed(...)),尤其用于逻辑复用或 provide/inject 场景
想让它可写?得手动加 set
computed 本身不支持赋值,是因为它默认只有 getter。要支持 myComputed.value = newValue,必须用对象语法声明,并提供 set 函数:
-
set接收赋的值,职责是反向更新它依赖的原始响应式数据 - 不要在
set里改myComputed.value自身,那会循环调用或报错 - 典型用法:表单联动、格式化输入(如把全名拆成 firstName/lastName)
不复杂但容易忽略:computed 的只读是“防误操作”的第一道关,而 readonly 才是守门员。











