Когда мы разрабатываем приложения, особенно сложные, часто возникает потребность работать с производными данными. Представьте: у вас есть исходные данные, но для отображения или логики вам нужны данные, основанные на них. Вот где вычисляемые свойства и наблюдатели становятся вашими лучшими друзьями. В этой статье мы разберём, как их использовать в Vue 3 с Composition API.

Вычисляемые свойства (Computed Properties)

Начнём с того, что вычисляемые свойства в Vue позволяют вам создавать производные данные на основе других реактивных переменных. Они похожи на методы, но с ключевым отличием — Vue автоматически кэширует результаты вычисления, пока зависимости не изменятся.

Почему не использовать методы?

Многие задаются вопросом: почему бы не использовать обычные методы для обработки производных данных? Ответ в производительности. Каждый раз, когда вызывается метод, он выполняется заново, даже если данные не изменились. Вычисляемые свойства, напротив, *запоминают* результат и не пересчитываются, если нет изменений в исходных данных. Это экономит ресурсы и ускоряет работу приложения.

Пример вычисляемого свойства

Представим простую задачу: у нас есть список товаров с ценами, и нам нужно подсчитать общую стоимость. Логично было бы сделать это с помощью вычисляемого свойства.

<template>
  <div>
    <p>Total price: {{ totalPrice }}</p>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const products = ref([
  { name: 'Product 1', price: 100 },
  { name: 'Product 2', price: 150 },
  { name: 'Product 3', price: 200 },
]);

const totalPrice = computed(() => {
  return products.value.reduce((sum, product) => sum + product.price, 0);
});
</script>

Здесь *totalPrice* — это вычисляемое свойство, которое автоматически пересчитывает общую сумму товаров только тогда, когда изменяется массив *products*.

Двусторонняя привязка и геттеры/сеттеры

Иногда требуется не просто получать значения, но и изменять их через вычисляемые свойства. Для этого в Vue 3 можно использовать геттеры и сеттеры.

Пример с двусторонней привязкой:

<template>
  <div>
    <p>Discounted price: {{ discountedPrice }}</p>
    <input v-model="discountedPrice" type="number" />
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const price = ref(200);

const discountedPrice = computed({
  get() {
    return price.value * 0.9; // 10% скидка
  },
  set(newValue) {
    price.value = newValue / 0.9;
  },
});
</script>

Теперь, когда вы вводите новое значение в поле, вычисляемое свойство автоматически изменяет исходную переменную *price* на основе скидки.

Наблюдатели (Watchers)

Теперь давайте поговорим о наблюдателях. Они позволяют *подслушивать* изменения конкретных реактивных переменных и выполнять действия в ответ на эти изменения. Если вычисляемые свойства предназначены для обработки данных, то наблюдатели отлично подходят для выполнения побочных эффектов.

Когда использовать наблюдатели?

Наблюдатели отлично подходят в случаях, когда нужно выполнять действия при изменении данных: отправить запрос на сервер, записать данные в локальное хранилище, вызвать стороннюю функцию и т.д. В отличие от вычисляемых свойств, которые просто возвращают значение, наблюдатели предназначены именно для выполнения кода.

Пример наблюдателя

Предположим, у нас есть форма с полем email, и мы хотим проверять его валидность каждый раз, когда пользователь вводит данные.

<template>
  <div>
    <input v-model="email" type="email" placeholder="Enter your email" />
    <p v-if="!isValid">Invalid email!</p>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue';

const email = ref('');
const isValid = ref(true);

watch(email, (newEmail) => {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  isValid.value = emailRegex.test(newEmail);
});
</script>

Здесь наблюдатель следит за переменной *email*, и каждый раз, когда она изменяется, запускается проверка на валидность с помощью регулярного выражения.

WatchEffect: автоматическое отслеживание зависимостей

Иногда бывает сложно точно указать, за какими именно переменными мы хотим следить. В таких случаях можно использовать *watchEffect*. Это более гибкий способ создания реактивных эффектов, когда Vue автоматически отслеживает зависимости.

Пример с watchEffect:

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script setup>
import { ref, watchEffect } from 'vue';

const count = ref(0);
const message = ref('');

const increment = () => {
  count.value++;
};

watchEffect(() => {
  if (count.value > 5) {
    message.value = 'Count is greater than 5!';
  } else {
    message.value = 'Keep going!';
  }
});
</script>

Здесь *watchEffect* автоматически следит за переменной *count* и обновляет сообщение на экране в зависимости от её значения. Главное преимущество *watchEffect* в том, что вам не нужно явно указывать, какие переменные отслеживать — Vue сам это делает за вас.

Наблюдатели для глубоких структур данных

Иногда нам нужно отслеживать изменения в сложных объектах или массивах. Для этого в Vue можно использовать флаг *deep*, чтобы наблюдатель реагировал на вложенные изменения.

Пример с глубоким наблюдением:

<script setup>
import { ref, watch } from 'vue';

const user = ref({
  name: 'Alice',
  age: 25,
  address: {
    city: 'New York',
    street: 'Broadway',
  },
});

watch(user, (newUser) => {
  console.log('User data changed:', newUser);
}, { deep: true });
</script>

В этом примере, если изменится любой атрибут объекта *user*, наблюдатель сработает. Без флага *deep* изменения вложенных объектов не будут отслеживаться.

Как выбрать: computed или watch?

  • Используйте *computed*, когда вам нужно получить производное значение на основе других реактивных данных.
  • Используйте *watch*, когда вам нужно выполнять побочные эффекты в ответ на изменения данных.

Заключение

Вычисляемые свойства и наблюдатели — это мощные инструменты Vue.js, которые позволяют гибко управлять данными и реагировать на изменения в приложении. Вычисляемые свойства облегчают работу с производными данными, обеспечивая оптимизированный и кэшированный доступ к результатам. Наблюдатели, в свою очередь, идеально подходят для выполнения действий, таких как запросы на сервер или валидация данных.

С пониманием этих концепций вы сможете создавать более эффективные и гибкие приложения на Vue 3 с использованием Composition API. В следующих статьях мы продолжим углубляться в особенности Vue, включая работу с классами, стилями и динамическими компонентами!

 

Комментарии

1

Без регистрации и смс