Vue оновлює шаблон лише тоді, коли змінюється реактивний стан - той, за яким система реактивності може стежити. Звичайна змінна такою не є.
<script setup>
let count = 0; // звичайна змінна
const increment = () => count++;
</script>
<template>
<button @click="increment">{{ count }}</button> <!-- завжди 0 -->
</template>
count справді збільшується в пам'яті, але Vue про це не знає й не перемальовує компонент.
Як правильно:
<script setup>
import { ref } from 'vue';
const count = ref(0);
const increment = () => count.value++;
</script>
Чому Vue не може стежити за звичайною змінною: JavaScript не дає способу перехопити присвоєння локальній змінній. Реактивність працює через перехоплення доступу до властивостей: ref - це об'єкт з властивістю value, reactive - проксі над об'єктом. Читання реєструє залежність, запис - сповіщає про зміну.
Коли звичайна змінна доречна:
- константи й дані, які не змінюються (
const MAX_ITEMS = 50); - функції-обробники;
- значення, що потрібні лише в логіці й не показуються в шаблоні (ідентифікатор таймера, екземпляр сторонньої бібліотеки).
Схожі пастки:
- заміна
reactive-об'єкта цілком:let state = reactive({...}); state = reactive({...})- шаблон стежить за старим проксі; - деструктуризація
reactiveчи props - отримані змінні не реактивні; - дані, отримані з
fetch, записані в звичайну змінну замістьref- перший рендер порожній, і після завантаження нічого не змінюється.
Підказка: якщо значення має з'являтися в шаблоні й змінюватися - воно має бути ref, reactive чи computed.