26-mini-vue getCurrentInstance

实现 getCurrentInstance

  1. 作用

    • getCurrentInstance 用于获取当前组件实例,通常在 setup 函数中使用
    • 可以获取组件的 propsslotsemit 等信息
    • 只能在 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
}
相关推荐
hxjhnct2 分钟前
Vue 实现多行文本“展开收起”
前端·javascript·vue.js
橙子的AI笔记3 分钟前
2025年全球最受欢迎的JS鉴权框架Better Auth,3分钟带你学会
前端·ai编程
百锦再3 分钟前
Vue大屏开发全流程及技术细节详解
前端·javascript·vue.js·微信小程序·小程序·架构·ecmascript
麻瓜呀5 分钟前
vue2之el-table表格多选改单选
javascript·vue.js·elementui
独自破碎E8 分钟前
你知道Spring Boot配置文件的加载优先级吗?
前端·spring boot·后端
龙仔CLL9 分钟前
vue3使用node-rsa报错buffer is not defined
javascript·vue.js
一树山茶10 分钟前
Vue变化响应
前端
黑土豆12 分钟前
一次真实的流式踩坑:fetchEventSource vs fetch流读取的本质区别
前端·javascript·ai编程
北辰alk13 分钟前
为什么 Vue 渲染列表时,不能随便用数组下标当 key?
vue.js