在 Vue 3 中,getCurrentInstance() 是一个用于获取当前组件实例 的内置 API,主要用于组合式 API(<script setup>)或组合式函数中访问组件的底层属性(如 ctx、proxy、appContext 等)。下面我会从「创建/使用条件」「核心用法」「注意事项」三个维度,用通俗易懂的方式讲解,并提供可直接运行的代码示例。

一、核心前提:getCurrentInstance() 的使用场景
getCurrentInstance() 不需要「创建」,而是直接调用,但有严格的使用条件:
- 必须在组件的生命周期内调用 :只能在
<script setup>、setup()函数、组合式函数(Composables)中使用,不能在异步回调(如setTimeout、Promise.then)或全局函数中直接调用(除非提前保存实例); - 仅适用于开发/内部逻辑 :Vue 官方不建议在业务代码中依赖它,更多用于封装通用组件/工具(如访问
$refs、$emit、全局属性等)。
二、完整使用示例
1. 基础用法(<script setup> 中)
vue
<template>
<div ref="contentRef">我是测试内容</div>
<button @click="logInstance">打印组件实例</button>
</template>
<script setup>
import { getCurrentInstance, onMounted } from 'vue'
// 1. 获取当前组件实例(核心步骤)
const instance = getCurrentInstance()
// 注意:直接在异步回调中调用会返回 null,需提前保存实例
setTimeout(() => {
console.log('异步中调用:', getCurrentInstance()) // null
console.log('提前保存的实例:', instance) // 正常获取
}, 1000)
// 2. 常用场景1:访问组件的 proxy(等同于 this,可访问 props、emit、refs 等)
const { proxy } = instance
// 或直接解构:const proxy = instance.proxy
// 3. 常用场景2:访问全局属性(如 main.js 中注册的 app.config.globalProperties.$api)
const globalProperties = instance.appContext.config.globalProperties
// 4. 常用场景3:访问 $refs(需在组件挂载后)
onMounted(() => {
console.log('访问 refs:', proxy.$refs.contentRef) // 获取 dom 元素
})
// 5. 常用场景4:手动触发 emit(等同于 setup 中的 emit 函数)
const logInstance = () => {
console.log('组件实例:', instance)
console.log('全局属性:', globalProperties)
// 手动触发自定义事件(等同于 emit('custom-event', '参数'))
proxy.$emit('custom-event', '我是参数')
}
</script>
2. 在组合式函数(Composables)中使用
封装通用工具函数时,通过 getCurrentInstance() 访问组件上下文,避免重复传参:
javascript
// src/composables/useGlobalApi.js
import { getCurrentInstance } from 'vue'
// 封装获取全局 API 的组合式函数
export const useGlobalApi = () => {
const instance = getCurrentInstance()
if (!instance) {
throw new Error('useGlobalApi 必须在组件内部调用!')
}
// 返回全局属性(如 main.js 中注册的 $api)
return instance.appContext.config.globalProperties.$api
}
在组件中使用该组合式函数:
vue
<script setup>
import { useGlobalApi } from '@/composables/useGlobalApi'
// 直接获取全局 API,无需传参
const $api = useGlobalApi()
// 调用全局 API
$api.getUserInfo().then(res => console.log(res))
</script>
3. 非 <script setup> 场景(setup() 函数)
vue
<script>
import { getCurrentInstance } from 'vue'
export default {
setup(props, { emit }) {
// 直接调用即可
const instance = getCurrentInstance()
console.log('组件实例:', instance)
return {
logInstance: () => {
console.log('proxy:', instance.proxy)
}
}
}
}
</script>
三、关键属性说明
获取到的 instance 实例包含以下常用属性(新手重点关注):
| 属性 | 作用 | 等同于 Vue 2 的 this.xxx |
|---|---|---|
proxy |
组件的代理对象,可访问 props、emit、refs、全局属性等 | this |
ctx |
组件上下文(轻量版 proxy,不建议业务使用) | - |
appContext |
应用上下文,可访问全局配置、全局组件、全局属性等 | this.$appContext |
props |
组件接收的 props 数据 | this.$props |
emit |
触发自定义事件的函数 | this.$emit |
四、注意事项(避坑重点)
- 避免在生产环境依赖
ctx:ctx是内部属性,生产环境会被压缩,可能导致属性名变化(如ctx变成_ctx),优先使用proxy; - 异步回调中需提前保存实例 :如
setTimeout、axios请求回调中直接调用getCurrentInstance()会返回null,需在同步代码中先保存instance; - 不要滥用 :Vue 3 设计理念是「无 this」,优先通过
defineProps、defineEmits、ref等官方 API 实现需求,仅在必要时使用getCurrentInstance(); - 全局组件/插件中慎用:在全局注册的组件或插件中调用,可能获取到错误的实例(如根组件实例)。
总结
getCurrentInstance()无需创建,直接调用即可获取当前组件实例,仅能在组件生命周期内(同步代码)使用;- 核心用途是访问组件底层属性(如
proxy替代this、全局属性、$refs等),优先使用proxy而非ctx; - 主要用于封装组合式函数/通用工具,业务代码中尽量避免依赖,遵循 Vue 3 「无 this」的设计理念。