2026.01.28
组件实例 -> getCurrentInstance 的实现
在开发过程中,有时我们需要访问组件实例本身,比如获取组件的属性、上下文或者其他内部状态。Vue 提供了 getCurrentInstance API,允许我们在 setup 函数或生命周期钩子中获取当前组件的实例。
在开发过程中,有时我们需要访问组件实例本身,比如获取组件的属性、上下文或者其他内部状态。Vue 提供了 getCurrentInstance API,允许我们在 setup 函数或生命周期钩子中获取当前组件的实例。
问题场景
让我们先通过一个示例来观察 getCurrentInstance 的使用场景:
<div id="app"></div>
<script type="module">
import { h, createApp, getCurrentInstance } from '../dist/vue.esm.js'
const Comp = {
setup() {
// 获取当前组件实例
const instance = getCurrentInstance()
console.log('🚀 ~ instance:', instance)
return () => {
return h('div', [
h('p', 'p'),
])
}
}
}
createApp(Comp).mount('#app')
</script>
核心问题:
getCurrentInstance只能在setup或生命周期钩子中使用- 需要在正确的时机设置和清除当前组件实例
- 类似于
effect的activeSub机制,需要一个全局变量来追踪当前实例
实现 getCurrentInstance
1. 基础架构设计
参考 effect 中 activeSub 的实现思路,我们只需要在 setup 执行前设置当前组件实例,执行完成后清除即可:
/**
* 全局变量,用于追踪当前正在执行的组件实例
* 类似于 effect 中的 activeSub
*/
let currentInstance = null
/**
* 获取当前组件实例
* 只能在 setup 或生命周期钩子中使用
*/
export function getCurrentInstance() {
return currentInstance
}
/**
* 设置当前组件实例
* 在 setup 执行前调用
*/
function setCurrentInstance(instance) {
currentInstance = instance
}
/**
* 清除当前组件实例
* 在 setup 执行完成后调用
*/
function unsetCurrentInstance() {
currentInstance = null
}
2. 在 setup 流程中集成
接下来,我们需要在 setupStateFulComponent 函数中集成实例的管理逻辑:
/**
* 设置有状态组件
*/
function setupStateFulComponent(instance) {
const { type } = instance
instance.proxy = new Proxy(instance.ctx, publicInstanceProxyHandlers)
if (isFunction(type.setup)) {
const setupContext = createSetupContext(instance)
instance.setupContext = setupContext
// 设置当前组件的实例
setCurrentInstance(instance)
// 执行 setup 函数
const setupResult = type.setup(instance.props, setupContext)
// 清除当前组件的实例
unsetCurrentInstance()
handleSetupResult(instance, setupResult)
}
if (!instance.render) {
instance.render = type.render
}
}
执行流程:
- 创建
setupContext,包含attrs、emit、slots、expose等上下文信息 - 调用
setCurrentInstance(instance)设置当前实例 - 执行
type.setup(),此时在setup内部可以调用getCurrentInstance()获取实例 - 调用
unsetCurrentInstance()清除当前实例,确保后续不会被误用 - 处理
setup的返回结果
总结
至此,我们完成了 getCurrentInstance 的实现:
1. 核心机制
- 使用全局变量
currentInstance追踪当前组件实例 - 类似
effect的activeSub模式,确保正确的作用域
2. API 设计
getCurrentInstance():获取当前组件实例setCurrentInstance():在setup执行前设置实例unsetCurrentInstance():在setup执行完成后清除实例
3. 使用限制
- 只能在
setup函数或生命周期钩子中使用 - 在
setup外部调用会返回null
4. 工作流程
setupStateFulComponent被调用时- 创建
setupContext后,设置currentInstance - 执行
setup函数,内部可通过getCurrentInstance()访问实例 setup执行完成后,清除currentInstance
这个实现确保了组件实例在正确的作用域内可访问