计算属性默认只读,因其本质是基于响应式依赖的缓存 getter 函数,无内置赋值逻辑;需显式定义 set 函数才能支持写入,实现双向绑定效果。

计算属性默认是只读的,所以直接赋值会报错“Cannot assign to read only property”。解决方法是为计算属性添加 setter,让它支持写入操作,从而实现类似双向绑定的效果。
为什么计算属性默认不可写?
Vue 中的计算属性(computed)本质是基于响应式依赖的缓存 getter 函数。它没有内置的赋值逻辑,因此尝试 obj.computedProp = newValue 时,JS 会触发默认的 setter(即 undefined),最终抛出只读错误。
只有显式定义了 set() 函数,Vue 才知道“当这个计算属性被赋值时,应该做什么”。
如何正确添加 Setter?
使用对象语法声明计算属性,在其中同时定义 get 和 set:
- get 负责返回派生值(必须有)
- set 接收一个参数(即你赋的值),通常用于更新源数据
- set 中不要直接修改计算属性本身,而是去改它依赖的响应式数据
示例:
computed: {
fullName: {
get() {
return this.firstName + ' ' + this.lastName
},
set(newValue) {
const parts = newValue.split(' ')
this.firstName = parts[0] || ''
this.lastName = parts[1] || ''
}
}
}
这样在模板中用 v-model="fullName" 就不会报错了。
Setter 的典型使用场景
- 格式化输入:如把用户输入的手机号自动加空格或横线,但保存时还原为纯数字
-
拆解复合字段:比如把 “年-月-日” 字符串赋给
dateString,setter 自动解析并设置year、month、day - 同步多个状态:一个开关控制多个布尔值,setter 统一更新它们
注意事项和常见坑
- setter 中不能调用
this.fullName = ...,否则造成无限循环 - 确保 setter 修改的是响应式数据(data / ref / reactive 中的属性)
- Vue 2 和 Vue 3 的写法一致,但 Composition API 中需用
computed(() => { ... }, { set() { ... } })形式 - 如果只写 get 不写 set,该计算属性仍是只读;反之,只写 set 没有意义(无法读取)

















