Реактивное состояние: ref
Состояние — данные компонента, которые меняются во время работы: число задач, текст в поле, открыто ли меню. Чтобы Vue замечал изменения и перерисовывал страницу, состояние объявляют реактивным. Основной способ — функция ref.
Обычная переменная не работает
<script setup>
let count = 0
</script>
<template>
<button @click="count++">Нажато: {{ count }}</button>
</template>Кнопка всегда показывает «Нажато: 0». Число в переменной растёт, но Vue об этом не знает и страницу не обновляет.
Функция ref
<!-- src/App.vue -->
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<button @click="count++">Нажато: {{ count }}</button>
</template>Теперь каждый клик увеличивает число на кнопке. ref(0) создаёт объект-обёртку с начальным значением 0. Vue следит за этим объектом и перерисовывает всё, где он используется.
Свойство .value
В скрипте значение лежит в свойстве .value. В шаблоне Vue достаёт его сам, поэтому там .value не пишут:
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment() {
count.value++
console.log(count.value)
}
</script>
<template>
<button @click="increment">Нажато: {{ count }}</button>
</template>После каждого клика число на кнопке растёт, а в консоли браузера (F12, вкладка Console) появляется новое значение: 1, 2, 3.
| Где | Чтение | Запись |
|---|---|---|
script setup | count.value | count.value = 5 |
template | count | count = 5 в обработчике |
Любые типы данных
ref принимает строки, числа, массивы и объекты. Для списка задач:
<script setup>
import { ref } from 'vue'
const todos = ref(['Купить хлеб', 'Позвонить Анне'])
function addTodo() {
todos.value.push('Новая задача')
}
</script>
<template>
<p>Задач: {{ todos.length }}</p>
<button @click="addTodo">Добавить</button>
</template>Каждый клик добавляет строку в массив, и счётчик «Задач» увеличивается. Vue замечает даже изменения внутри массива — методы push, splice, присваивание элемента.
Почему const
Переменную с ref объявляют через const: сама обёртка не меняется, меняется её .value. Это защищает от случайной замены всего объекта.
Частая ошибка
Забыть .value в скрипте:
<script setup>
import { ref } from 'vue'
const count = ref(0)
function reset() {
count = 0 // Ошибка: константе нельзя присвоить значение
}
</script>Правильно — count.value = 0. Если в скрипте сравнение вроде count > 5 никогда не срабатывает, скорее всего, вы сравниваете обёртку, а не число.