watch и watchEffect в чем разница
Содержание
В данной статье используется синтаксис Composition API <script setup>
watch
и watchEffect
во Vue.js выполняют схожие функции, но имеют некоторые ключевые отличия.
Использование watch
watch
позволяет вам следить за изменениями в реактивных источниках данных и выполнять какие-либо действия в ответ на эти изменения. Основные особенности:
- Указание cлежения: Вы явно указываете, за какими свойствами или реактивными источниками следует наблюдать.
- Ленивость:
watch
по умолчанию является "ленивым", то есть не выполняется при инициализации, а только в ответ на изменения. - Доступ к старым и новым значениям: При вызове коллбека
watch
предоставляет как старое, так и новое значения отслеживаемого свойства. - Более детальная конфигурация: Позволяет настроить такие параметры, как глубокое наблюдение (
deep
), отложенное выполнение (immediate
), и т.д.
Как пишется:
watch(() => someReactiveProperty, (newValue, oldValue) => { // Выполняется при изменении someReactiveProperty } )
Пример использования watch
Рассмотрим ситуацию, где watch
может быть особенно полезен:
<script setup> import {ref, watch} from 'vue' const someValue = ref(0) const anotherValue = ref('начальное значение') watch(someValue, (newValue, oldValue) => { if (newValue > oldValue) { anotherValue.value = 'значение увеличилось' } else if (newValue < oldValue) { anotherValue.value = 'значение уменьшилось' } }) </script>
В этом примере, watch
используется для отслеживания изменений в someValue
и соответствующего обновления anotherValue
в зависимости от того, увеличилось ли значение или уменьшилось по сравнению с предыдущим состоянием. Это пример сценария, где watch
является более подходящим выбором по сравнению с watchEffect
, так как вам нужно реагировать на изменения в определенной зависимости и при этом имеется специфическая логика сравнения старого и нового значений.
Использование watchEffect
watchEffect
автоматически определяет реактивные зависимости и выполняется при их изменении. Особенности:
- Автоматическое обнаружение зависимостей:
watchEffect
автоматически отслеживает все реактивные свойства, используемые внутри коллбека. - Не ленив: Выполняется немедленно при создании и затем при изменении любых реактивных зависимостей.
- Не предоставляет старые значения: В отличие от
watch
,watchEffect
не предоставляет старые значения. - Проще для простых сценариев: Более подходит для сценариев, когда вам нужно просто реагировать на изменения без необходимости точного контроля.
Как пишется:
watchEffect(() => { // Код, который реагирует на изменения любых реактивных свойств, использованных здесь })
Несколько отслеживаемых данных
Использования watchEffect
, где отслеживается несколько реактивных источников данных, может быть полезен в сценариях, где вам нужно выполнять действия, зависящие от нескольких реактивных свойств или состояний. Это позволяет легко реагировать на изменения в любом из этих источников без необходимости создания множественных отдельных наблюдателей.
Пример использования watchEffect
Допустим, у вас есть компонент, который отображает информацию о пользователе, и вы хотите обновлять эту информацию каждый раз, когда изменяется имя пользователя или его статус. У вас есть два реактивных свойства: userName
и userStatus
.
<script setup> import { ref, watchEffect } from 'vue' const userName = ref('Иван') const userStatus = ref('активен') watchEffect(() => { console.log(`Пользователь: ${userName.value}, Статус: ${userStatus.value}`) // Здесь может быть код, который выполняет что-то в зависимости от этих свойств }) function updateUser() { userName.value = 'Мария' // Изменение userName вызовет watchEffect userStatus.value = 'неактивен' // Изменение userStatus также вызовет watchEffect } </script>
Зачем это нужно
В этом примере watchEffect
используется для автоматического отслеживания изменений в userName
и userStatus
. Всякий раз, когда любое из этих свойств изменяется, код внутри watchEffect
будет автоматически перезапускаться. Это удобно в следующих случаях:
- Сокращение кода: Вместо создания отдельных
watch
для каждого свойства, можно использовать одинwatchEffect
, который справится со всеми зависимостями. - Автоматическое отслеживание:
watchEffect
автоматически определяет, какие реактивные свойства используются, и отслеживает их. Это уменьшает риск пропуска важных зависимостей. - Реактивность и гибкость: Когда нужно реагировать на изменения в нескольких свойствах,
watchEffect
предоставляет простой и эффективный способ сделать это.
Таким образом, watchEffect
идеально подходит для сценариев, где вам нужно отслеживать изменения в нескольких реактивных источниках данных и выполнять действия, когда любой из них изменяется.
Сравнение watchEffect и computed и watch
watchEffect
: Этот метод используется для выполнения побочных эффектов в ответ на изменения в реактивных данных.watchEffect
автоматически отслеживает все зависимости внутри своего коллбека и реагирует на любые изменения этих зависимостей. Примеры использования включают выполнение асинхронных операций, обновление DOM (вне шаблона Vue), работу с браузерным API и так далее.computed
: Это реактивное свойство, которое автоматически вычисляется и кэшируется на основе своих реактивных зависимостей.computed
идеально подходит для ситуаций, когда вам нужно вывести новое значение на основе реактивных данных и это значение необходимо повторно использовать в вашем шаблоне или скрипте. Оно обеспечивает оптимизацию производительности за счет кэширования и перевычисляется только тогда, когда изменяются его зависимости.watch
: Этот метод предназначен для реакции на изменения конкретных реактивных данных или вычисляемых свойств. Основное отличие отwatchEffect
заключается в том, что вы явно указываете, за какими свойствами следует наблюдать иwatch
предоставляет доступ к предыдущему и текущему значениям этих свойств. Это особенно полезно, когда вам нужно сравнить старое и новое значения или когда реакция на изменения требует более сложной логики, например, если изменение одного значения должно вызвать изменение другого.
Выбор между computed
и watchEffect
Выбор между computed
и watchEffect
в Vue.js зависит от конкретной задачи, которую вы хотите решить. Вот ключевые различия и сценарии использования для каждого из них:
computed
- Оптимизация: Вычисляемые свойства (
computed
) оптимизированы для вычисления значений на основе реактивных зависимостей. Значения кэшируются, и пересчёт происходит только тогда, когда одна из зависимостей изменяется. - Использование в шаблонах:
computed
идеально подходит для случаев, когда вы хотите использовать вычисленные значения в шаблонах. - Возврат значения:
computed
возвращает значение, которое можно использовать в других частях вашего приложения. - Примеры: Преобразование данных для отображения, фильтрация списков, объединение нескольких реактивных свойств в одно.
const fullName = computed(() => `${firstName.value} ${lastName.value}`);
watchEffect
- Побочные эффекты:
watchEffect
предназначен для выполнения побочных эффектов в ответ на изменение реактивных данных. Он автоматически отслеживает все использованные внутри коллбека реактивные зависимости. - Не возвращает значение:
watchEffect
не предназначен для создания новых реактивных данных, которые могут быть использованы в других частях приложения. - Автоматическое отслеживание:
watchEffect
удобен, когда вам нужно реагировать на изменения в нескольких реактивных источниках данных без необходимости явно указывать, за чем следить. - Примеры: Запросы к API при изменении данных, обновление Document title, слежение за размерами элемента.
watchEffect(() => { console.log(`Имя пользователя изменилось на ${userName.value}`) })
Когда и что использовать?
- Используйте
computed
, когда вам нужно вычислить реактивное значение на основе одного или нескольких реактивных источников данных, особенно если это значение будет использоваться в шаблоне. - Используйте
watchEffect
, когда вам нужно выполнить побочные эффекты в ответ на изменения любых реактивных данных, используемых внутри функции, и вам не требуется возвращаемое значение.
Выбор между computed
и watchEffect
зависит от того, создаёте ли вы реактивное значение, которое будет использоваться в других местах вашего приложения (в этом случае лучше computed
), или вы хотите выполнить некоторые действия в ответ на изменения (здесь лучше подойдёт watchEffect
).
Геттеры и сеттеры
Во Vue.js понятия геттеров и сеттеров часто ассоциируются с вычисляемыми свойствами (computed
). Вычисляемые свойства можно определять с использованием геттеров и, необязательно, сеттеров. В то время как watch
и watchEffect
не используются для определения геттеров и сеттеров напрямую, они скорее реагируют на изменения уже существующих реактивных данных.
Пример с computed
(геттер и сеттер)
Допустим, у вас есть компонент, который работает с пользовательским именем, но вы хотите хранить это имя в нижнем регистре в вашем приложении, в то время как в интерфейсе оно должно отображаться в привычном формате.
<script setup> import {ref, computed} from 'vue' // Реактивное свойство для хранения имени в нижнем регистре const userNameStored = ref('иван') // Вычисляемое свойство с геттером и сеттером const userName = computed({ // Геттер возвращает значение в привычном формате get: () => userNameStored.value.charAt(0).toUpperCase() + userNameStored.value.slice(1), // Сеттер обновляет значение, преобразуя его в нижний регистр set: (newValue) => userNameStored.value = newValue.toLowerCase() }) </script>
В этом примере:
- Геттер (
get
) автоматически вызывается, когда вы пытаетесь получить доступ кuserName
. Он возвращает значениеuserNameStored
, преобразованное в привычный формат. - Сеттер (
set
) вызывается, когда вы присваиваете значениеuserName
. Он обновляетuserNameStored
, преобразуя новое значение в нижний регистр.
Отличия от watch
и watchEffect
watch
и watchEffect
не предполагают использование геттеров и сеттеров. Они используются для отслеживания изменений в реактивных свойствах или вычисляемых значениях и выполнения некоторых действий в ответ на эти изменения. Они не предназначены для прямого управления данными или их преобразования, как это делается в вычисляемых свойствах с геттерами и сеттерами.
Резюме
В заключение, концепции watch
, watchEffect
и вычисляемых свойств (computed
) в Vue.js представляют собой мощные инструменты для реактивного программирования и управления состоянием приложения. watch
и watchEffect
дают возможность отслеживать изменения в реактивных данных и выполнять соответствующие действия, причём watch
предоставляет более детальный контроль и доступ к предыдущим значениям, в то время как watchEffect
удобен для автоматического отслеживания всех зависимостей внутри функции. Вычисляемые свойства (computed
), с их геттерами и сеттерами, являются ключевым инструментом для создания реактивных данных, которые автоматически обновляются при изменении их зависимостей.
Применение этих методов значительно повышает гибкость и эффективность кода, позволяя легко создавать интерактивные и реактивные пользовательские интерфейсы. Вы можете использовать эти инструменты для создания сложных интерактивных приложений с чистым и понятным кодом и обеспечивая высокую производительность вашего приложения на Vue.js.