Состояние
Во введении был счётчик, который работал, и обещание объяснить, как он устроен. Вот это объяснение. Для начала попробуйте тот же счётчик с обычной переменной:
<script setup>
let stamps = 0;
function addStamp() {
stamps++;
console.log(stamps);
}
</script>
<template>
<p>Штампов: {{ stamps }}</p>
<button @click="addStamp">Добавить штамп</button>
</template>Нажмите кнопку три раза, и консоль покажет:
1
2
3Переменная действительно меняется, но страница по-прежнему показывает «Штампов: 0». Почему? Vue отрисовывает шаблон: создаёт из него элементы страницы со значениями, которые переменные имеют в этот момент. Заново он отрисовывает шаблон, только когда узнаёт, что изменилось что-то из используемого в шаблоне. Обычная переменная не умеет сообщить, что она изменилась, поэтому Vue ничего не узнаёт, и страница остаётся такой, какой её отрисовали в первый раз.
Для значений, которые меняются, у Vue есть ref():
<script setup>
import { ref } from "vue";
const stamps = ref(0);
function addStamp() {
stamps.value++;
}
</script>
<template>
<p>Штампов: {{ stamps }}</p>
<button @click="addStamp">Добавить штамп</button>
</template>Теперь каждый клик добавляет штамп, и страница сразу его показывает. Что здесь нового:
import { ref } from "vue";берёт из Vue функциюref, чтобы вы могли использовать её в этом файле.ref(0)создаёт реф — небольшой объект, который хранит значение, здесь 0. В скрипте значение — этоstamps.value, его вы и меняете. В шаблоне по-прежнему простоstamps; почему так, объяснит следующее упражнение.- Когда
stamps.valueменяется, Vue узнаёт об этом и заново отрисовывает шаблон с новым значением. Страницу вы сами не меняете, как меняли её черезtextContentв курсе JavaScript. Вы меняете данные, а страницу меняет Vue.
Данные приложения, которые могут меняться, например число штампов, называются его состоянием. Значения, за которыми Vue так следит, реактивные: страница реагирует, когда они меняются.
Типичная ошибка: нет строки import. Страница остаётся пустой, а консоль пишет ReferenceError: ref is not defined.
Задание
- 1
Нажмите «Следующий, пожалуйста» несколько раз. Консоль показывает, как число растёт, а страница нет. Сделайте
servingрефом, чтобы страница показывала новый номер после каждого клика. (Вызовconsole.log()можно удалить.) - 2
Добавьте после кнопки «Следующий, пожалуйста» кнопку «Начать заново». Её обработчик, функция
startOver(), возвращает номер к 1.