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