computed属性默认只读,需通过getter/setter对象实现“伪双向绑定”;setter负责解析新值并更新源数据,须做容错处理且保持同步无副作用。

Computed 属性本身是只读的,不能直接赋值;但 Vue 允许你通过定义 带 getter 和 setter 的 computed 对象,实现“看起来像双向绑定”的复杂计算逻辑——本质上是把写操作映射到对源数据的解析与更新上。
为什么需要自定义 setter?
默认 computed 只有 getter,比如:
computed: { fullName() { return this.firstName + ' ' + this.lastName } }
这时 vm.fullName = 'John Doe' 会静默失败。要支持赋值,必须显式提供 setter,并在里面手动拆解、赋值给底层响应式字段。
基础写法:getter + setter 配对
在 computed 中用对象语法声明,同时定义 get 和 set:
- getter 负责返回计算结果(如拼接、格式化、派生)
- setter 接收新值,解析它,并更新一个或多个响应式源数据
示例:用完整姓名字符串反向设置姓和名
computed: {
fullName: {
get() {
return `${this.firstName} ${this.lastName}`.trim();
},
set(newValue) {
const parts = newValue.split(/\s+/).filter(p => p);
this.firstName = parts[0] || '';
this.lastName = parts[1] || '';
}
}
}
处理更复杂的场景
当计算依赖多个状态、含格式转换或校验时,setter 需更谨慎:
- 输入可能非法(如空字符串、超长、非数字),setter 中应做容错(如
if (!newValue)提前 return) - 若计算涉及异步或副作用(如发请求),不要在 setter 里做 —— computed 的 setter 应保持同步、无副作用
- 若需从复合字符串还原多个字段(如日期字符串
'2023-10-05'→year/month/day),在 setter 中用正则或new Date()解析后赋值 - 可配合
watch或onUpdated做后续响应,但 setter 本身只负责状态同步
注意事项与常见陷阱
这种模式不是真正的“双向绑定”,而是语义上的双向映射:
- setter 中修改源数据会触发 getter 重新求值,可能造成意外循环(如 setter 改了
firstName,而 getter 又依赖它 —— 正常,Vue 会去重执行) - 避免在 getter 中执行耗时操作(如 deepClone、大量遍历),否则每次访问都卡顿
- 不建议在 setter 中调用
this.$nextTick或修改 DOM —— 违背响应式设计原则 - 组合式 API(Vue 3)中写法类似:
computed({ get() {}, set(v) {} }),逻辑一致











