The problem:
Whenever I try to set two ref variables with the same Object they will share the same reactivity inside of the component.
When I click the checkbox ref1.test and ref2.test will change both, while the v-model is only for ref1.test
App.vue
<template>
ref1: {{ ref1 }} ref2: {{ ref2 }}
<input type="checkbox" v-model="ref1.test" />
</template>
<script lang="ts">
import { defineComponent, ref } from "vue";
import { TestModel } from "@/TestModel";
export default defineComponent({
setup() {
const testObj = { test: false } as TestModel;
const ref1 = ref<TestModel>({});
ref1.value = testObj;
const ref2 = ref<TestModel>({});
ref2.value = testObj;
return {
ref1,
ref2,
};
},
});
</script>
TestModel.ts
export interface TestModel {
test?: boolean;
}
Can someone explain this or tell me if this is normal? (I know how to solve this, but I just wanna know why this is happening)
CodePudding user response:
The two ref's properties (ref1
,ref2
) refers to the same object which testObj
and any change in one of those properties affects the original one, this is a javascript behavior, to avoid it try to clone the object deeply using structuredClone
:
const testObj = { test: false } as TestModel;
const ref1 = ref<TestModel>({});
ref1.value = structuredClone(testObj);
const ref2 = ref<TestModel>({});
ref2.value = structuredClone(testObj);
CodePudding user response:
Because Vue's reactivity is just proxy. It uses proxy so it knows what to do when a value change.
Proxy A (ref1) -> read/write testObj
Proxy B (ref2) -> read/write testObj
Docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
According to the Vue's docs
ref
does the following:
If an object is assigned as a ref's value, the object is made deeply reactive with reactive().
Docs: https://vuejs.org/api/reactivity-core.html#ref
reactive
does the following:
Returns a reactive proxy of the object.
...
The returned object and its nested objects are wrapped with ES Proxy