Вычисляемые свойства: computed
Учимся выводить значения из других значений через computed: автоматический пересчёт, кеширование и чем это лучше обычного метода.
computed — реактивное вычисляемое свойство: оно зависит от других реактивных данных, пересчитывается только когда они меняются, и кеширует результат.
Зачем нужны вычисляемые свойства
Часто значение нужно не хранить, а выводить из других: полное имя из имени и фамилии, итог корзины из списка товаров, отфильтрованный список. Можно писать такое выражение прямо в шаблоне, но он быстро становится нечитаемым. computed выносит логику и делает её реактивной:
<template>
<p>{{ firstName }} {{ lastName }}</p>
<p>Полное имя: {{ fullName }}</p>
</template>
<script setup>
import { ref, computed } from 'vue'
const firstName = ref('Аня')
const lastName = ref('Иванова')
const fullName = computed(() => firstName.value + ' ' + lastName.value)
</script>
Как только меняется firstName или lastName, fullName пересчитывается сам. В шаблоне computed используется как обычный ref — без .value.
Кеширование — главное отличие от метода
Можно было бы сделать метод getFullName() и вызывать его в шаблоне. Но метод выполняется при каждой перерисовке, даже если данные не менялись. computed же кеширует результат и пересчитывает его, только когда меняется зависимость. Прочувствуем разницу через счётчик вызовов:
let calls = 0;
// Имитация computed с кешем по зависимости
function makeComputed(getDep, fn) {
let cachedDep, cachedVal;
return () => {
const dep = getDep();
if (dep !== cachedDep) { // пересчитать только если зависимость изменилась
cachedDep = dep;
cachedVal = fn(dep);
calls++;
}
return cachedVal;
};
}
let price = 100;
const total = makeComputed(() => price, p => p * 1.2);
console.log(total()); // считает
console.log(total()); // берёт из кеша
console.log(total()); // берёт из кеша
price = 200;
console.log(total()); // зависимость изменилась — считает заново
console.log("Реальных пересчётов:", calls);
Вывод:
120 120 120 240 Реальных пересчётов: 2
Хотя total() вызвали 4 раза, реальных вычислений было только 2 — остальное взято из кеша. Именно так экономит ресурсы computed в больших списках и тяжёлых вычислениях.
Фильтрация списка через computed
<script setup>
import { ref, computed } from 'vue'
const search = ref('')
const users = ref(['Аня', 'Борис', 'Артём', 'Вера'])
const filtered = computed(() =>
users.value.filter(u => u.toLowerCase().includes(search.value.toLowerCase()))
)
</script>
computed против method
| computed | метод | |
| Кеширование | да, по зависимостям | нет, считает каждый раз |
| Вызов в шаблоне | как свойство: {{ x }} | как функция: {{ x() }} |
| Для чего | производные данные | действия по событию |
Итог
computedсоздаёт производное значение из других реактивных данных.- Пересчитывается автоматически при изменении зависимостей.
- Кеширует результат — в отличие от метода, который выполняется при каждой перерисовке.
- В шаблоне используется как обычный ref, без
.value.