You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue组件渲染时扩展运算符/深拷贝触发无限更新循环但Object.assign正常

问题原因解析

三者的本质区别

  • Object.assign(parent, { path: '', noShowingChildren: true }):直接修改传入的原parent对象,方法返回值就是修改后的原parent对象,始终是同一个引用地址
  • 扩展运算符{ ...parent, xxx }:创建一个全新的对象,和原parent对象没有引用关系,每次执行都会生成一个新的引用地址
  • JSON.parse(JSON.stringify(parent))深拷贝:同样是创建完全独立的新对象,每次执行都会生成新的引用地址

无限循环的触发逻辑

你将hasOneShowingChild方法直接写在了模板的v-if判断条件中,Vue组件每次渲染都会执行这个方法:

  1. 使用扩展运算符/深拷贝时,每次方法执行都会给响应式变量this.onlyOneChild赋值一个全新的对象
  2. Vue的响应式系统检测到onlyOneChild发生变化,就会触发组件重新渲染
  3. 重新渲染又会再次执行hasOneShowingChild,再次给onlyOneChild赋新对象,由此形成无限更新循环

Object.assign正常运行的原因

你使用Object.assign时是直接修改原parent对象,第一次修改完成后,后续每次执行Object.assign(parent, xxx)都是修改同一个对象,返回的也是同一个引用地址。此时给this.onlyOneChild赋值的始终是同一个引用的对象,Vue检测到值没有发生变化,就不会触发重复渲染,因此不会出现死循环。

优化建议

你当前的Object.assign写法存在不符合Vue单向数据流规范的问题:parent是组件接收的props对象,直接修改props可能会导致父组件数据被意外污染,后续父组件更新时容易出现不可预期的问题。
建议的修复方案:

  • 不要将包含响应式变量赋值逻辑的方法直接放在模板的渲染条件中,可以将相关逻辑移到computed计算属性或者watch监听器中处理
  • 给onlyOneChild赋值前先判断是否已经是目标对象,避免重复赋值:
// 示例逻辑
if (!this.onlyOneChild || this.onlyOneChild.id !== parent.id) {
  const template = { ...parent , path: '', noShowingChildren: true }
  this.onlyOneChild = template
}

内容的提问来源于stack exchange,提问作者J.Kuai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:15:01