computed

↑ 4.1 Vue 3: основы, компоненты, Composition API · ← Предыдущая · → Следующая

Обязательно~3 мин чтенияУровень: middle

Зачем это на собесе

Кэширование и ленивость computed, отличие от методов и watch.

Объяснение

computed — производное значение: пересчитывается лениво и кэшируется, пока не изменятся зависимости.

const items = ref<Item[]>([]);
const query = ref("");
const filtered = computed(() => items.value.filter(i => i.name.includes(query.value)));
const total = computed(() => filtered.value.reduce((s, i) => s + i.price, 0));
 
// Writable computed
const fullName = computed({
  get: () => `${first.value} ${last.value}`,
  set: (v: string) => { [first.value, last.value] = v.split(" "); },
});
computedМетод в шаблонеwatch
Кэшданет (вызывается при каждом рендере)—
Возвращает значениедаданет (побочные эффекты)
Зависимостиавтоматически—явные
Побочные эффектынет (должна быть чистой)возможныдля эффектов

Правила:

  • Функция должна быть чистой: без мутаций, запросов, DOM.
  • Возврат нового массива/объекта при каждом вычислении допустим; computed пересчитывается только при смене зависимостей.
  • Vue 3.4+: computed не запускает эффекты, если значение не изменилось (по Object.is).
  • Доступ к предыдущему значению: computed((prev) => ...).

Цепочки computed образуют граф зависимостей; пересчёт происходит только запрошенных узлов.

Нюансы и подводные камни

  • Побочные эффекты в computed ломают предсказуемость.
  • Изменение массива методом, не отслеживаемым (например, мутация вне Vue) не приведёт к пересчёту.
  • Асинхронная логика в computed не поддерживается: используйте watch, watchEffect или Vue Query.
  • Дорогое вычисление на большой коллекции: разделяйте на несколько computed.
  • computed не выполняется, пока не прочитан.

Практика

  1. Замените метод filteredItems() в шаблоне на computed и измерьте число вычислений.
  2. Реализуйте writable computed для полного имени.
  3. Постройте цепочку computed: фильтр → сортировка → страница.

Вопросы с ответами

Связанные темы