实现 getCurrentInstance
-
作用
getCurrentInstance用于获取当前组件实例,通常在setup函数中使用- 可以获取组件的
props、slots、emit等信息 - 只能在
setup函数或生命周期钩子中使用 - 还可以获取虚拟节点的类型,根据不同类型做不同的处理
-
实现思路
- 创建一个全局变量来存储当前正在执行的组件实例
- 在
setup函数执行前,将当前实例存储到全局变量中 - 在
setup函数执行后,清空全局变量 getCurrentInstance函数返回当前存储的实例
-
具体实现
js// runtime-core/component.ts let currentInstance = null; // ✅ 创建全局变量存储当前实例 export function getCurrentInstance() { return currentInstance; // ✅ 返回当前实例 } function setupStatefulComponents(instance: any) { const Component = instance.vnode.type; const { setup } = Component; instance.proxy = new Proxy({ _: instance }, PublicInstanceProxyHandlers); if (setup) { currentInstance = instance; // ✅ 在 setup 执行前,保存当前实例 const setupResult = setup(shallowReadonly(instance.props), { emit: instance.emit, }); currentInstance = null; // ✅ setup 执行后,清空当前实例 handleSetupResult(instance, setupResult); } } -
导出 getCurrentInstance
js// runtime-core/index.ts export { createApp } from "./createApp"; export { h } from "./h"; export { renderSlots } from "./helpers/renderSlots"; export { createTextVNode } from "./vnode"; export { getCurrentInstance } from "./component"; // ✅ 导出 getCurrentInstance -
使用示例
js// example/App.js import { h, getCurrentInstance } from "../../lib/guide-mini-vue.esm.js"; export const App = { name: "App", setup() { const instance = getCurrentInstance(); // ✅ 获取当前组件实例 console.log("当前组件实例:", instance); console.log("props:", instance.props); console.log("slots:", instance.slots); return {}; }, render() { return h("div", {}, "app"); }, }; -
注意事项
getCurrentInstance只能在setup函数执行期间调用- 如果在
setup函数外部调用,会返回null - 主要用于高级场景,如组件库开发、工具函数等
-
重构
优点: 将 currentInstance 相关的逻辑进行封装,代码更加清晰易懂,后续维护也更方便。
js
// runtime-core/component.ts
function setupStatefulComponents(instance: any) {
const Component = instance.vnode.type
const { setup } = Component
// 注意:这里的虚拟节点是属于 component 的
instance.proxy = new Proxy({_: instance}, PublicInstanceProxyHandlers)
if(setup) {
setCurrentInstance(instance)
const setupResult = setup(shallowReadonly(instance.props),{
emit: instance.emit
})
setCurrentInstance(null)
handleSetupResult(instance, setupResult) // 将状态结果进心处理
}
}
let currentInstance = null; // ✅ 创建全局变量存储当前实例
export function getCurrentInstance(instance: any) {
return currentInstance
}
export function setCurrentInstance(instance: any) { // ✅ 设置当前实例
currentInstance = instance
}