vue.jsvuejs3refvue-reactivity

Identity checks with ref values in Vue3 not working as expected


This official Vue.js documentation claims that the ref() API in Vue 3 uses getters and setters.

In Vue 3, Proxies are used for reactive objects and getter / setters are used for refs.

This would imply, according to my understanding, positive identity checks when comparing an object with the value of its reference. The following example seems to prove the contrary.

Is there a gap in my understanding? Is the abovementioned article out-of-date?

const obj = {};
const objRef = Vue.ref(obj);

Vue.createApp({
setup() {
    return {
        answer: obj === objRef.value,
    };
}
}).mount('#app');
<script src="https://unpkg.com/vue@3"></script>

<div id="app">
      <code>obj === objRef.value</code> evaluates to <span>{{ answer }}</span>
</div>


Solution

  • ref creates deeply reactive object with value property:

    const objRef = ref(obj);
    console.log(obj !== objRef.value); // true
    console.log(obj === toRaw(objRef.value)); // true
    

    This means that nested properties like objRef.value.foo.bar are reactive, and nested refs are unwrapped.

    If this is not desirable then shallowRef should be used instead:

    const objRef = shallowRef(obj);
    console.log(obj === objRef.value); // true