计算属性死循环本质是getter中修改了自身依赖的响应式数据,导致无限递归;应只读不写,副作用改用watch或methods处理。

计算属性 computed 报死循环,本质是它内部依赖的数据在求值过程中又被它自己修改了,触发重新计算,形成无限递归。这不是 Vue 的 bug,而是响应式逻辑的必然结果——关键在于避免“读时写、写时读”的双向耦合。
检查 computed 是否意外修改了响应式数据
最常见的死循环场景:在 computed 的 getter 中直接给 data、ref 或 reactive 对象的属性赋值。
- ❌ 错误示例:
computed(() => {<br> this.count++ // 直接修改响应式数据<br> return this.count;<br>})
- ✅ 正确做法:计算属性只做“读取 + 返回”,不带副作用。修改动作应移至 methods、watch 或事件回调中。
警惕深层嵌套对象的隐式修改
对 reactive 对象的嵌套属性做解构、展开或 JSON 序列化/反序列化,可能无意中打破响应式连接,或在某些操作中触发 setter 链式更新。
立即学习“前端免费学习笔记(深入)”;
- 例如:
const { name } = this.user解构后修改name不会触发响应;但若后续又赋值回this.user.name = name,且该赋值发生在 computed 内,就可能引发循环。 - 建议:在 computed 中只安全地读取嵌套字段(如
this.user?.profile?.age),避免任何赋值、push、splice、Object.assign 等变更操作。
区分 computed 和 watch 的职责边界
当需求是“某值变化后执行副作用(如发请求、更新另一个状态)”,别硬塞进 computed —— 它的设计初衷是派生状态,不是触发行为。
- ❌ 用 computed 发请求、调 API、修改其他 ref:极易因响应式依赖反复触发。
- ✅ 改用
watch监听源数据变化,再执行副作用。需要缓存结果?可配合一个额外的ref存储计算值。
调试技巧:快速定位循环源头
在 computed 的 getter 开头加一句 console.trace('computed triggered'),观察控制台堆栈是否重复出现同一 computed 名称;也可在 Vue Devtools 的 “Reactivity” 面板中查看该计算属性的依赖图,确认是否有不该存在的反向依赖(比如它自己出现在自己的依赖列表里)。
不复杂但容易忽略。


















