26-mini-vue getCurrentInstance

实现 getCurrentInstance

  1. 作用

    • getCurrentInstance 用于获取当前组件实例,通常在 setup 函数中使用
    • 可以获取组件的 props、slots、emit 等信息
    • 只能在 setup 函数或生命周期钩子中使用
    • 还可以获取虚拟节点的类型,根据不同类型做不同的处理
  2. 实现思路

    • 创建一个全局变量来存储当前正在执行的组件实例
    • 在 setup 函数执行前,将当前实例存储到全局变量中
    • 在 setup 函数执行后,清空全局变量
    • getCurrentInstance 函数返回当前存储的实例
  3. 具体实现

    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);
      }
    }
  4. 导出 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
  5. 使用示例

    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");
      },
    };
  6. 注意事项

    • getCurrentInstance 只能在 setup 函数执行期间调用
    • 如果在 setup 函数外部调用,会返回 null
    • 主要用于高级场景,如组件库开发、工具函数等
  7. 重构

    优点: 将 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
}
相关推荐
程序员大阳9 小时前
副队长JavaScript教程(52)-DOM操作元素的内容
javascript·dom·innertext·innerhtml·value·内容操作
山雀~11 小时前
CSP 安全漏洞修复
前端·网络协议
裕波11 小时前
苏千|从 cnpm 到 Vite+:AI 时代的开发者体验演进
javascript
console.log('npc')11 小时前
周期任务功能完整实现:CRON 编辑器 + 模板变量 + 执行历史
javascript·vue.js·编辑器
程序员大阳11 小时前
副队长JavaScript教程(58)-基于DOM的网页留言板开发
javascript·实例·dom·案例·留言板
陌离11 小时前
Go-Gui:一套 无限接近 现代化UI的 GPU绘制界面组件框架
前端
咚咚咚小柒11 小时前
【前端】LangChain.js学习
前端·javascript·人工智能·typescript·langchain·vue·ai编程
2401_8858850412 小时前
巴林语音通知接口如何对接?系统告警语音API接入教程
android·前端·网络·python·语音识别
java1234_小锋12 小时前
【技术专题】CSS3 网页技术 - CSS3 盒模型
前端·css·css3
计算机魔术师12 小时前
手握芯片、又要吞下开源分发入口,英伟达被盯上了
前端