I'm kinda new to composition API in vue3 and I'll be glad if someone could explain to me why...
this works:
<template>
<h1>{{ foo }}</h1>
</template>
<script setup>
import { ref, onMounted } from "vue";
const foo = ref('');
onMounted(() => {
foo.value = 'bar';
});
</script>
and this don't:
<template>
<h1>{{ foo }}</h1>
</template>
<script setup>
import { onMounted } from "vue";
let foo;
onMounted(() => {
foo = 'bar';
});
</script>
I can't access foo
inside onMounted
neither I am able to declare a variable inside onMounted
and access it outside the lifecycle hook. Why does it happen?
It's not that foo isn't updating, because it is, it's just not triggering a rerender of the UI because foo is not reactive. At the time the screen is initially rendered (right before onMounted runs), foo has no value, so that's what is rendered. Vue is not tracking changes to foo, so even when foo changes, it's not reason enough for Vue to rerender the screen. If it was reactive, Vue would rerender the screen every time foo changes, hence why the first example works.
Vue only updates the UI when something reactive changes. If non-reactive variables update, Vue doesn't care. If something else reactive caused a rerender, <h1>{{ foo }}</h1>
would update to show the latest value of foo
Example:
<template>
<h1>{{ foo }}</h1>
<div @click="rerender">click me {{ bar }}</div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
let foo
let bar = ref(0)
const rerender = () => {
bar.value++
}
onMounted(() => {
foo = 'bar'
})
</script>
The Vue docs go into more in-depth explanation as to how reactivity works and is definitely worth a read!