Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як змінилася стабільність computed у Vue 3.4 і коли computed усе одно запускає зайві оновлення?

З Vue 3.4 обчислювана властивість запускає залежні ефекти (рендер, watch) лише якщо її значення справді змінилося, а не щоразу, коли змінилися її залежності.

const count = ref(1)
const isEven = computed(() => count.value % 2 === 0)

watchEffect(() => console.log(isEven.value))

count.value = 3   // isEven лишився false - ефект не запускається
count.value = 5   // теж
count.value = 6   // true - запускається

До 3.4 кожна зміна count змушувала перезапустити все, що читало isEven, навіть з тим самим результатом.

Порівняння - за Object.is. Для примітивів це працює чудово. А от computed, що щоразу повертає новий об'єкт чи масив, завжди вважається зміненим:

const activeItems = computed(() => items.value.filter((i) => i.active))

Будь-яка зміна items (навіть поля, яке не впливає на фільтр) дає новий масив - залежні компоненти оновлюються.

Ручна стабілізація - через попереднє значення, яке Vue передає першим аргументом:

const summary = computed((oldValue) => {
  const next = { done: doneCount.value, total: total.value }
  if (oldValue && oldValue.done === next.done && oldValue.total === next.total) {
    return oldValue     // те саме посилання - залежні не оновлюються
  }
  return next
})

Обов'язково обчислювати нове значення повністю до порівняння, щоб Vue зібрав усі залежності на кожному запуску.

Практичні висновки:

  • computed, що повертає примітив (boolean, number, рядок), - найкращий кандидат для передачі в дочірні компоненти й шаблони: стабільний автоматично;
  • для об'єктів, що рідко змінюються по суті, - стабілізація через oldValue, коли вимірювання показують проблему;
  • побічних ефектів у computed бути не повинно: завдяки ліньому й кешованому обчисленню невідомо, скільки разів і коли він виконається.

Пов'язане: watch з deep: true на великих об'єктах теж дорогий - кожна зміна обходить усю структуру. З Vue 3.5 deep приймає число - глибину обходу.

Докладніше в документації: Продуктивність: стабільність computed

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання