Чем отличаются computed от watch?
В Vue.js computed и watch используются для реактивного отслеживания изменений данных, но они выполняют разные задачи и применяются в разных контекстах. Несмотря на то, что и computed, и watch реагируют на изменения реактивных свойств, их поведение, назначение и производительность различаются.
Что такое computed?
computed — это вычисляемое свойство, которое зависит от других реактивных данных и автоматически пересчитывается, когда эти данные изменяются. Оно кэшируется, то есть пересчёт происходит только при изменении зависимостей.
export default {
data() {
return {
firstName: 'John',
lastName: 'Doe'
};
},
computed: {
fullName() {
return this.firstName + ' ' + this.lastName;
}
}
}
В этом примере fullName автоматически обновляется, когда меняется firstName или lastName, но не пересчитывается без необходимости — он кэширован до следующего изменения зависимостей.
Особенности computed
-
Кэширование: computed значение сохраняется, и пересчёт происходит только тогда, когда его зависимости реально изменяются.
-
Используется как свойство: В шаблоне или коде вы обращаетесь к нему как к обычному свойству: this.fullName.
-
Рекомендуется для производных данных: computed подходит для ситуаций, когда вам нужно отображать данные, производные от других данных.
Что такое watch?
watch — это способ наблюдать за изменением одного или нескольких реактивных свойств и выполнять какую-либо побочную операцию, когда эти свойства меняются.
export default {
data() {
return {
searchQuery: ''
};
},
watch: {
searchQuery(newVal, oldVal) {
this.fetchResults(newVal);
}
},
methods: {
fetchResults(query) {
// запрос на сервер
}
}
}
Здесь watch следит за searchQuery и вызывает метод fetchResults каждый раз, когда значение searchQuery изменяется.
Особенности watch
-
Не кэшируется: watch не возвращает значение и не используется для получения данных — он запускает функцию при изменении наблюдаемого свойства.
-
Используется для побочных эффектов: Сюда входят вызовы API, работа с localStorage, манипуляции с DOM, запуск анимаций, асинхронные операции и т. п.
-
Позволяет следить за сложными структурами: Можно отслеживать не только простые значения, но и вложенные объекты, массивы и реактивные ссылки.
Сравнение: computed vs watch
Характеристика | computed | watch |
---|---|---|
Назначение | Вычисление и кэширование производных значений | Реакция на изменения и выполнение побочных действий |
--- | --- | --- |
Возвращает значение | Да | Нет |
--- | --- | --- |
Кэшируется | Да | Нет |
--- | --- | --- |
Синтаксис | Свойство объекта | Функция-наблюдатель |
--- | --- | --- |
Подходит для | Представления (UI) и логики вычислений | Асинхронных операций и внешних эффектов |
--- | --- | --- |
Асинхронность | Не поддерживает асинхронность напрямую | Поддерживает асинхронные функции |
--- | --- | --- |
Множественные зависимости | Да (Vue сам отслеживает зависимости) | Нужно указывать явно или использовать функцию |
--- | --- | --- |
Управление вложенными структурами | Нет (ограничено) | Да (через deep: true) |
--- | --- | --- |
Примеры использования
Пример 1: Использование computed для форматирования данных
computed: {
formattedPrice() {
return \`$${this.price.toFixed(2)}\`;
}
}
Здесь мы получаем красиво отформатированную цену. Кэширование важно: если price не изменился — пересчёт не нужен.
Пример 2: Использование watch для API-запроса
watch: {
city(newCity) {
this.getWeatherData(newCity);
}
}
Этот подход позволяет запускать запрос на сервер каждый раз, когда пользователь выбирает новый город. Здесь важно выполнение побочного эффекта, а не возвращение нового значения.
Использование watch с дополнительными опциями
Vue позволяет более гибко управлять поведением watch с помощью настроек:
watch: {
user: {
handler(newVal, oldVal) {
this.saveToLocalStorage(newVal);
},
deep: true, // Следить за вложенными изменениями
immediate: true // Запустить сразу при инициализации
}
}
-
deep: true — нужен, если user является объектом или массивом и вы хотите следить за вложенными изменениями.
-
immediate: true — вызывает обработчик сразу при создании компонента (без первого изменения).
Возможность реактивного слежения с функцией
Vue поддерживает формат watch(() => expr, callback) через Composition API:
import { ref, watch } from 'vue';
const count = ref(0);
watch(() => count.value, (newVal, oldVal) => {
console.log(\`Count changed: ${oldVal} → ${newVal}\`);
});
Можно отслеживать выражения, сразу получать старое и новое значение и настраивать поведение так же, как в Options API.
Когда использовать computed
-
Для логики отображения, например, объединения имени и фамилии.
-
Для фильтрации и сортировки массивов.
-
Для получения реактивных значений, производных от других реактивных данных.
-
Когда нужно кэшировать результат для повышения производительности.
Когда использовать watch
-
Когда нужно реагировать на изменения и выполнять действия (например, API-запросы, сохранение в хранилище, валидацию).
-
Когда работаете с асинхронными действиями.
-
Когда нужно следить за вложенными структурами (deep).
-
Когда необходимо реагировать немедленно при загрузке компонента (immediate).