Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why normal objects become reactive automatically in Vue3?

In this article there is an example. It says the normal object wont be 'reactive'.

I made a test in this codesandbox, and found that changes to the normal object (even the normal string) can automatically change the view.

<template>
  {{ personName }} <!-- will change to Amy, why? -->
  {{ person.name }} <!-- will change to Amy, why? -->
  {{ personRef.name }}
  {{ personReactive.name }}
  <button @click="changeName('Amy')">changeName</button>
</template>

<script setup>
import { ref, reactive } from "vue";

let personName = "John";
const person = { name: "John" };
const personRef = ref({ name: "John" });
const personReactive = reactive({ name: "John" });
const changeName = (name) => {
  personName = name;
  person.name = name;
  personRef.value.name = name;
  personReactive.name = name;
};
</script>

How did this happen? Did I miss something in the Vue document?

I've tried the Vue SFC Playground which gives the same result.

like image 242
PaintyJoy Avatar asked Oct 26 '25 17:10

PaintyJoy


1 Answers

The normal variables are not becoming reactive. What is really happening is a re-render that is caused by the changeName() method. The re-render is caused because you changed the values of the reactive variables. As a result, The DOM is updated with the latest values correctly shown for both normal and reactive variables.

To illustrate this I have created a fork of your sandbox with this code:

<template>
  {{ personName }}
  {{ person.name }}
  {{ personRef.name }}
  {{ personReactive.name }}
  <button @click="changeReactiveName('Amy')">changeReactiveName</button>
  <button @click="changeNormalName('Fanoflix')">changeNormalName</button>
</template>

<script setup>
import { ref, reactive } from "vue";

let personName = "John";
const person = { name: "John" };
const personRef = ref({ name: "John" });
const personReactive = reactive({ name: "John" });

const changeReactiveName = (name) => {
  personRef.value.name = name;
  personReactive.name = name;
};

const changeNormalName = (name) => {
  personName = name;
  person.name = name;
};
</script>

When you change only the non-reactive variables by calling changeNormalName(), the change (correctly) does not cause a DOM re-render and you will not see the changes reflected in the DOM.

Once you call the changeReactiveName() method, the DOM will be re-rendered to incorporate the changes done to the reactive variables. Hence, The DOM will also render the new values of the non-reactive variables which you updated previously and will show Fanoflix.

For a better understanding, read how Vue handles rendering: docs

like image 86
Fanoflix Avatar answered Oct 29 '25 01:10

Fanoflix