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

Vue3修改reactive属性后两次console.log打印值相同问题

问题产生原因

这个现象不是Vue3的响应式异常,是两个机制共同导致的:

  1. reactive()返回的是目标对象的Proxy代理实例,本质属于引用类型,所有对这个对象的访问、修改都指向同一块内存空间,不存在赋值时的快照拷贝。
  2. 浏览器控制台对引用类型值的console.log打印采用懒读取机制:执行打印语句时不会立刻序列化对象内容存储快照,只会在你首次点击展开这条打印记录时,才去读取对象当前的内存值渲染详情。

所以你在两次打印语句之间修改了对象属性,等到你在控制台展开查看两条日志时,读到的已经是修改完成后的对象状态,自然会看到两次打印的对象值完全一致。

这个行为和Vue无关,纯JS环境下可以直接复现:

const obj = { a: 0, b: { c: 1 } }
console.log(obj, "第一次打印")
obj.a = 10
console.log(obj, "第二次打印")

控制台展开两条日志后,看到的a值均为10。

正确打印各时间点对象实际值的方案

核心思路是打印时生成当前对象的独立快照,断开和原对象的引用关联,常用方法如下:

  • 深拷贝生成快照后打印
    优先使用浏览器原生支持的structuredClone()做深拷贝,支持绝大多数JS数据类型(包括嵌套对象、数组、Date、Map、Set等),不会受后续原对象修改影响:
    const ob1 = reactive({ a: 0, b: { c: 1 } })
    console.log(structuredClone(ob1), "修改前快照")
    ob1.a = 10
    console.log(structuredClone(ob1), "修改后快照")
    
    如果需要兼容极低版本浏览器,也可以用JSON.parse(JSON.stringify(ob1))做深拷贝,注意这个方法无法序列化函数、Symbol、循环引用的对象。
  • 直接打印序列化后的字符串
    临时调试时可以直接把对象转成格式化JSON字符串打印,字符串是基础类型,打印后就不会再变化:
    console.log(JSON.stringify(ob1, null, 2), "修改前")
    
  • 打印具体的基础类型属性
    如果只需要观测单个属性的值,直接访问属性打印即可,基础类型是值传递,不存在引用关联问题:
    console.log(ob1.a, ob1.b.c, "修改前属性值")
    

内容的提问来源于stack exchange,提问作者tr93

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 04:30:52