watch и watchEffect в чем разница

В данной статье используется синтаксис Composition API <script setup>

watch и watchEffect во Vue.js выполняют схожие функции, но имеют некоторые ключевые отличия.

Использование watch

watch позволяет вам следить за изменениями в реактивных источниках данных и выполнять какие-либо действия в ответ на эти изменения. Основные особенности:

  1. Указание cлежения: Вы явно указываете, за какими свойствами или реактивными источниками следует наблюдать.
  2. Ленивость: watch по умолчанию является "ленивым", то есть не выполняется при инициализации, а только в ответ на изменения.
  3. Доступ к старым и новым значениям: При вызове коллбека watch предоставляет как старое, так и новое значения отслеживаемого свойства.
  4. Более детальная конфигурация: Позволяет настроить такие параметры, как глубокое наблюдение (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 автоматически определяет реактивные зависимости и выполняется при их изменении. Особенности:

  1. Автоматическое обнаружение зависимостей: watchEffect автоматически отслеживает все реактивные свойства, используемые внутри коллбека.
  2. Не ленив: Выполняется немедленно при создании и затем при изменении любых реактивных зависимостей.
  3. Не предоставляет старые значения: В отличие от watch, watchEffect не предоставляет старые значения.
  4. Проще для простых сценариев: Более подходит для сценариев, когда вам нужно просто реагировать на изменения без необходимости точного контроля.

Как пишется:

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 будет автоматически перезапускаться. Это удобно в следующих случаях:

  1. Сокращение кода: Вместо создания отдельных watch для каждого свойства, можно использовать один watchEffect, который справится со всеми зависимостями.
  2. Автоматическое отслеживание: watchEffect автоматически определяет, какие реактивные свойства используются, и отслеживает их. Это уменьшает риск пропуска важных зависимостей.
  3. Реактивность и гибкость: Когда нужно реагировать на изменения в нескольких свойствах, 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.

Написать комментарий