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

Що таке effectScope і коли він потрібен поза компонентами?

Кожен computed, watch і watchEffect, створений у setup компонента, Vue автоматично прив'язує до компонента і зупиняє, коли компонент знищується. Поза компонентом такої прив'язки немає - ефекти живуть, доки їх не зупинити вручну.

effectScope збирає всі ефекти, створені всередині, в одну групу, яку можна зупинити одним викликом:

import { effectScope, ref, watch, computed } from 'vue';

const scope = effectScope();

scope.run(() => {
  const query = ref('');
  const results = computed(() => search(query.value));

  watch(query, (value) => saveToHistory(value));
  watchEffect(() => console.log(results.value.length));
});

// пізніше - зупинити все разом
scope.stop();

Де це потрібно:

1. Спільний стан composable для кількох компонентів («спільний composable»): ефекти мають жити, поки є хоча б один споживач, і зупинитися, коли зник останній:

function createSharedComposable(factory) {
  let consumers = 0;
  let state, scope;

  return () => {
    consumers++;
    if (!state) {
      scope = effectScope(true);   // detached: не прив'язаний до поточного компонента
      state = scope.run(factory);
    }
    onScopeDispose(() => {
      if (--consumers === 0) {
        scope.stop();
        state = scope = undefined;
      }
    });
    return state;
  };
}

Саме так влаштований createSharedComposable у VueUse.

2. Бібліотеки й сховища. Pinia створює effectScope для кожного стора - тому $dispose() прибирає всі його спостерігачі.

3. Тести - ізолювати й гарантовано прибрати ефекти між тестами.

4. Тимчасові ефекти - наприклад, на час відкритого модального вікна чи активного режиму редагування.

onScopeDispose(fn) - реєструє очищення для поточної області: в компоненті спрацює при його знищенні, в effectScope - при stop(). Тому composable, що використовує onScopeDispose замість onUnmounted, працює і в компонентах, і поза ними.

getCurrentScope() - дізнатися, чи код виконується всередині області (наприклад, щоб composable попередив, що його викликали поза компонентом).

Без цього composable, викликаний поза setup (у сторі, в роутері, в модулі), створює спостерігачів, які ніколи не зупиняться, - витоки пам'яті в довгоживучих SPA.

Докладніше в документації: effectScope

Перевір себе

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

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