onUnmounted is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup()
情况

[Vue warn]: onUnmounted is called when there is no active component instance to be associated with. Lifecycle injection APIs can only be used during execution of setup(). If you are using async setup(), make sure to register lifecycle hooks before the first await statement.
说明
虽然上面的警告说组件不活跃
代码执行时必须处于 setup 的同步上下文中。
简单来说就是,比如我在setup script最后一行写了console.log('setup')。
那么onUnmounted等生命周期的调用必须在这个打印之前。
vue3中有个getCurrentInstance api,可以检测当前是否在setup同步上下文。
getCurrentInstance() === null不代表组件不存在或已卸载- 它只代表当前代码不在 setup 同步执行期间
- 组件完全正常运行时,
getCurrentInstance()也可能返回null
<script setup>
import { onUnmounted, onMounted, getCurrentInstance } from 'vue'
const instance = getCurrentInstance()
console.log('setup 同步阶段 - 组件实例:', instance)
const fetchCategories = () => {
return new Promise(resolve => {
setTimeout(() => {
console.log('fetchCategories 完成')
resolve(['category1', 'category2'])
}, 1000)
})
}
const testOnUnmounted = () => {
const currentInstance = getCurrentInstance()
console.log('testOnUnmounted 中 - 组件实例:', currentInstance)
onUnmounted(() => {
console.log('onUnmounted 回调执行')
})
}
onMounted(async () => {
console.log('onMounted 开始')
await fetchCategories()
console.log('await 之后,准备调用 testOnUnmounted')
testOnUnmounted()
})
</script>
<template>
<div class="scenario">
<h3>测试场景:onMounted + async/await</h3>
<div class="code-block">
<pre><code>onMounted(async () => {
await fetchCategories() // 模拟耗时操作
testOnUnmounted() // ❌ await 之后调用
})
function testOnUnmounted() {
onUnmounted(() => { ... }) // 警告!
}</code></pre>
</div>
<div class="warning">
<strong>问题分析:</strong>
<p>虽然代码在 onMounted 中,但 onMounted 的回调函数本身不是 setup 同步阶段。</p>
<p>当 onMounted 回调执行时,setup 已经执行完毕,组件实例上下文已经清除。</p>
<p>await 之后调用 onUnmounted,会触发警告。</p>
</div>
<div class="tips">
<h4>控制台输出:</h4>
<p>打开浏览器控制台查看日志,观察组件实例的变化</p>
</div>
</div>
</template>
<style scoped>
.scenario {
padding: 20px;
}
h3 {
color: #868e96;
margin-bottom: 16px;
}
.code-block {
background: #1e1e1e;
color: #d4d4d4;
padding: 16px;
border-radius: 8px;
overflow-x: auto;
margin-bottom: 16px;
}
.code-block code {
font-family: 'Consolas', monospace;
font-size: 13px;
}
.warning {
background: #fff5f5;
border: 1px solid #ffc9c9;
border-radius: 8px;
padding: 12px 16px;
color: #c92a2a;
font-size: 14px;
margin-bottom: 16px;
}
.warning p {
margin: 8px 0 0 0;
}
.warning p:first-child {
margin-top: 0;
}
.tips {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 16px;
}
.tips h4 {
margin-bottom: 8px;
color: #495057;
}
.tips p {
margin: 0;
color: #495057;
}
</style>

浙公网安备 33010602011771号