Home > Blockchain >  Why normal objects become reactive automatically in Vue3?
Why normal objects become reactive automatically in Vue3?

Time:01-04

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.

CodePudding user response:

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

  • Related