Vì inject, provide, lifecycle hook (onMounted, onUnmounted) và việc gắn effect vào scope đều dựa vào instance component đang active.
- Vue set instance này ngay trước khi chạy
setup()và gỡ ngay sau khisetup()trả về. - Sau một
await, code chạy ở microtask khác — instance không còn active.
js
<script setup>
// wrong: instance context is lost after await
const data = await fetchData()
onMounted(() => { /* warning: called when there is no active instance */ })
const api = inject(ApiKey) // returns undefinedHệ quả cụ thể:
- onMounted/onUnmounted không đăng ký → cleanup không chạy → rò rỉ listener/timer.
- inject trả undefined dù cha có provide.
- watch/computed tạo sau await không thuộc scope component → không tự dừng khi unmount.
Cách xử lý: gọi mọi composable ở đầu setup, đưa phần async vào trong composable (trả về ref loading/data và tự fetch trong onMounted). Nếu bắt buộc dùng top-level await (<Suspense>), hãy đăng ký hook/inject trước dòng await đầu tiên. Với code chạy ngoài component (vd callback), bọc bằng effectScope() để tự quản lý vòng đời effect.