未绑定v-model的reactive变量为何随ref变量同步变化?
问题原因
你这是对象引用共享导致的。res.data是后端返回的同一个对象,你把它同时赋值给transaction.value和pbl,相当于这两个变量指向了内存里的同一个对象。不管改哪个变量的属性,本质上都是在修改同一个对象的内容,所以它们会同步变化。
另外还要注意:你一开始用let pbl = reactive({}),但后面直接pbl = res.data会把pbl从reactive代理对象改成普通对象,丢失响应性,这也是个隐藏问题。
解决方案
核心是给两个变量创建独立的对象副本,让它们指向不同的内存地址。常用的复制方法有三种,根据你的数据结构选择:
1. 对象展开运算符(适合简单无嵌套的对象)
修改请求成功后的代码:
.then((res) => { // 复制原始数据给pbl,用reactive包裹保持响应性 pbl = reactive({...res.data}); // 复制一份给transaction作为可修改的副本 transaction.value = {...res.data}; })
2. structuredClone(适合嵌套对象、数组,现代浏览器支持)
如果你的res.data有多层嵌套,用这个更稳妥:
.then((res) => { const rawData = structuredClone(res.data); pbl = reactive(rawData); transaction.value = rawData; })
3. JSON序列化反序列化(兼容旧浏览器,但无法处理函数、Symbol等特殊类型)
.then((res) => { const rawData = JSON.parse(JSON.stringify(res.data)); pbl = reactive(rawData); transaction.value = rawData; })
更规范的写法:用ref统一管理pbl
推荐把pbl也改成ref,和transaction保持一致,避免reactive的赋值陷阱:
// 初始化时就用ref const transaction = ref({}); const pbl = ref({}); const getPayByLinkTransaction = () => { axios({ method: "get", url: "pay-by-link", params: { merchantUuid: import.meta.env.VITE_MERCHANT_UUID, uuid: route.params.uuid, }, }) .then((res) => { const rawData = {...res.data}; transaction.value = rawData; pbl.value = {...res.data}; }) .catch((e) => { console.log(e); }); }
这样修改后,transaction和pbl就是完全独立的两个对象,修改文本框的transaction.reference时,pbl.reference会保持原始值不变。
内容的提问来源于stack exchange,提问作者Dally
相关产品推荐
相关产品推荐

