import { defineComponent, onBeforeUpdate, onUnmounted, watch, type PropType } from "vue-demi"; import { ModContext } from "../types/ModContext"; import { InvokerItem } from "./InvokerItem"; let idCount = 0; export type InvokerModName = string; export default defineComponent({ props: { height: { type: String, default: () => "auto", }, scroll: { type: Boolean, default: () => false, }, items: { type: Array, default: () => undefined as InvokerItem[] | undefined, }, name: { type: String as PropType | undefined, default: () => undefined, required: false, } }, emits: ["destroyed"], setup(props, { slots, expose, emit }) { /** Invoker实例ID */ const id = ++idCount; /** vue实例上下文,此处获取的是Receiver的vue组件实例 */ let receiver: ModContext | null = null; window["MES_MOD_INVOKERS"] ||= {}; window["MES_MOD_INVOKERS"][id] = { getRenderContext, initFinish, receiver, }; /** 主动更新 */ function updateComponent() { // 判断子页面vue对象是否存在 receiver?.Update(); // 强制渲染 } // 子组件调用 function eventCallback(type: string, ...args: any[]) { switch (type) { case "created": initFinish(args[0]); break; } } /** 当Receiver初始化完毕后触发 */ function initFinish(context: ModContext) { receiver = context; console.log('[Mod-Invoker]initFinish') } function getRefs() { const refs = receiver?.refs; if (!refs) throw new Error("[Mod-Invoker] Receiver not found"); return refs; } // vue3 渲染上下文 function getRenderContext() { return props.items; } expose({ getRefs, getRenderContext, eventCallback, initFinish, }); watch( () => props.items, () => { updateComponent(); } ); onBeforeUpdate(() => { }); onUnmounted(() => { console.log("[Mod-Invoker] invoker-destroyed"); emit('destroyed'); }); return (h) => { if (slots.default) { return
{slots.default()}
; } return ( ); }; }, });