Начните с ref
ref создаёт реактивную обёртку значения. В JavaScript к нему обращаются через .value. В шаблоне верхнеуровневый ref обычно разворачивается автоматически. Это правило не означает, что любое вложенное значение в любой структуре разворачивается одинаково.
Функция computed подходит для производного значения: например, отфильтрованных статей. Не храните результат фильтра отдельно, если его всегда можно получить из списка и поисковой строки.
Фильтр с одним источником данных
Это пример однофайлового компонента для проекта Vue со сборкой. У каждой статьи есть устойчивый идентификатор, который используется как key.
<script setup>
import { ref, computed } from "vue";
const query = ref("");
const articles = ref([
{ id: "grid", title: "CSS Grid" },
{ id: "vue", title: "Реактивность Vue" }
]);
const filtered = computed(() => {
const term = query.value.trim().toLocaleLowerCase("ru");
return articles.value.filter(article =>
article.title.toLocaleLowerCase("ru").includes(term)
);
});
</script>
<template>
<label>Поиск <input v-model="query"></label>
<ul>
<li v-for="article in filtered" :key="article.id">
{{ article.title }}
</li>
</ul>
</template>Разделяйте вычисление и действие
Вычисляемое свойство должно возвращать результат. Сетевой запрос, запись в хранилище и другие побочные эффекты размещайте в обработчиках событий или наблюдателях, когда они действительно нужны.
Не добавляйте watch для простой синхронизации двух значений, если второе можно получить через computed. Меньше сохранённых копий данных — меньше мест, где они способны разойтись.
Попробуйте сами
Добавьте выбор категории и сообщение об отсутствии результатов. Получайте список из двух фильтров через одно вычисляемое свойство.
Всегда ли нужен глобальный store?
Нет. Состояние одного компонента можно хранить локально. Общее хранилище полезно, когда данные и действия действительно нужны нескольким независимым частям приложения.
Документация и следующий шаг
Продолжите практику: Форма, которую можно заполнить с клавиатуры.