В Vue 3 жизненный цикл компонентов расширен Composition API, где
одним из ключевых хуков является onUnmounted. Этот хук
вызывается один раз при демонтаже компонента и
предназначен для выполнения очистки ресурсов, отмены подписок и
остановки сторонних процессов. В тестировании важно убедиться, что
логика внутри onUnmounted корректно выполняется, особенно
при сложных взаимодействиях с внешними сервисами или глобальными
состояниями.
onUnmountedonUnmounted импортируется из vue и
регистрируется внутри функции setup компонента:
import { ref, onUnmounted } from 'vue';
export default {
setup() {
const intervalId = ref(null);
intervalId.value = setInterval(() => {
console.log('tick');
}, 1000);
onUnmounted(() => {
clearInterval(intervalId.value);
});
return { intervalId };
},
};
В этом примере хук обеспечивает очистку интервала при демонтаже. В
тестах важно проверить, что функция clearInterval
вызывается именно при размонтировании компонента.
Vue Test Utils предоставляет методы mount и
shallowMount для создания экземпляров компонентов. Для
тестирования onUnmounted используется метод
unmount, который симулирует размонтирование
компонента и запускает все соответствующие хуки жизненного
цикла.
import { mount } from '@vue/test-utils';
import ComponentWithUnmount from '@/components/ComponentWithUnmount.vue';
jest.useFakeTimers();
describe('ComponentWithUnmount', () => {
it('вызывает очистку интервала при размонтировании', () => {
const wrapper = mount(ComponentWithUnmount);
const intervalId = wrapper.vm.intervalId;
wrapper.unmount();
expect(clearInterval).toHaveBeenCalledWith(intervalId);
});
});
Ключевые моменты:
wrapper.unmount() гарантирует вызов
onUnmounted.jest.useFakeTimers().mount и shallowMount поддерживают
как обычные компоненты, так и компоненты с Composition API.onUnmounted часто используется для отмены подписок на
внешние события:
import { ref, onUnmounted } from 'vue';
export default {
setup() {
const count = ref(0);
const handle = setInterval(() => {
count.value++;
}, 1000);
onUnmounted(() => {
clearInterval(handle);
});
return { count };
},
};
Тест для проверки корректной очистки:
it('очищает интервал при размонтировании', () => {
const wrapper = mount(ComponentWithInterval);
const intervalHandle = wrapper.vm.count;
wrapper.unmount();
// Проверка, что интервал остановлен
jest.advanceTimersByTime(5000);
expect(wrapper.vm.count).toBe(intervalHandle);
});
Здесь важно понимать, что после размонтирования компонент больше
не обновляет состояние, а любые попытки взаимодействия
с ref не должны изменять значения.
onUnmounted может использоваться для отмены подписок на
события DOM или API. Например, слушатель событий:
import { onUnmounted } from 'vue';
export default {
setup() {
const handleClick = () => console.log('clicked');
window.addEventListener('click', handleClick);
onUnmounted(() => {
window.removeEventListener('click', handleClick);
});
},
};
Тестирование с Vue Test Utils:
it('удаляет обработчик события при размонтировании', () => {
const addSpy = jest.spyOn(window, 'addEventListener');
const removeSpy = jest.spyOn(window, 'removeEventListener');
const wrapper = mount(ComponentWithEvent);
wrapper.unmount();
expect(addSpy).toHaveBeenCalledWith('click', expect.any(Function));
expect(removeSpy).toHaveBeenCalledWith('click', expect.any(Function));
});
Проверка работы хука здесь сводится к контролю вызова функций очистки. Это особенно важно при тестировании компонентов с глобальными эффектами, чтобы избежать утечек памяти и ошибок при повторном монтировании.
onUnmountedВ некоторых случаях нужно выполнять асинхронные действия, например отменять подписки на API или сетевые запросы:
import { onUnmounted } from 'vue';
export default {
setup() {
const controller = new AbortController();
fetch('/api/data', { signal: controller.signal });
onUnmounted(() => {
controller.abort();
});
},
};
Тест с моками:
it('прерывает fetch при размонтировании', () => {
const abortSpy = jest.spyOn(AbortController.prototype, 'abort');
const wrapper = mount(ComponentWithFetch);
wrapper.unmount();
expect(abortSpy).toHaveBeenCalled();
});
Асинхронные операции в onUnmounted следует тщательно
тестировать, чтобы гарантировать, что ресурсы не остаются активными
после демонтажа.
unmount для проверки хуков
размонтирования.Эффективное тестирование onUnmounted обеспечивает
стабильность приложения и предотвращает утечки ресурсов, особенно при
работе с внешними сервисами, таймерами и подписками.