vue-mod-page/src/components/Invoker.tsx

118 lines
2.5 KiB
TypeScript
Raw Normal View History

2024-12-19 13:51:07 +08:00
import {
defineComponent,
onBeforeUpdate,
onUnmounted,
watch,
2025-05-08 16:29:04 +08:00
type PropType
2024-12-19 13:51:07 +08:00
} from "vue-demi";
import { ModContext } from "../types/ModContext";
import { InvokerItem } from "./InvokerItem";
2024-12-19 13:51:07 +08:00
let idCount = 0;
2025-05-08 16:29:04 +08:00
export type InvokerModName = string;
2024-12-19 13:51:07 +08:00
export default defineComponent({
props: {
height: {
type: String,
default: () => "auto",
},
scroll: {
type: Boolean,
default: () => false,
},
items: {
2025-05-08 16:29:04 +08:00
type: Array,
default: () => undefined as InvokerItem[] | undefined,
2024-12-19 13:51:07 +08:00
},
2025-05-08 16:29:04 +08:00
name: {
type: String as PropType<InvokerModName> | undefined,
default: () => undefined,
required: false,
}
2024-12-19 13:51:07 +08:00
},
emits: ["destroyed"],
setup(props, { slots, expose, emit }) {
/** Invoker实例ID */
2024-12-19 13:51:07 +08:00
const id = ++idCount;
/** vue实例上下文此处获取的是Receiver的vue组件实例 */
let receiver: ModContext | null = null;
2024-12-19 13:51:07 +08:00
window["MES_MOD_INVOKERS"] ||= {};
window["MES_MOD_INVOKERS"][id] = {
getRenderContext,
initFinish,
receiver,
2024-12-19 13:51:07 +08:00
};
/** 主动更新 */
function updateComponent() {
// 判断子页面vue对象是否存在
receiver?.Update(); // 强制渲染
2024-12-19 13:51:07 +08:00
}
// 子组件调用
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')
2024-12-19 13:51:07 +08:00
}
2024-12-19 13:51:07 +08:00
function getRefs() {
const refs = receiver?.refs;
if (!refs) throw new Error("[Mod-Invoker] Receiver not found");
return refs;
2024-12-19 13:51:07 +08:00
}
// vue3 渲染上下文
function getRenderContext() {
return props.items;
}
expose({
getRefs,
getRenderContext,
eventCallback,
initFinish,
});
watch(
() => props.items,
() => {
updateComponent();
}
);
onBeforeUpdate(() => {
2024-12-19 13:51:07 +08:00
});
onUnmounted(() => {
console.log("[Mod-Invoker] invoker-destroyed");
emit('destroyed');
2024-12-19 13:51:07 +08:00
});
return (h) => {
if (slots.default) {
2024-12-19 13:51:07 +08:00
return <div>{slots.default()}</div>;
}
return (
<iframe
src={props.url.replace('{id}',id.toString())}
scrolling={props.scroll ? "yes" : "no"}
style={`border: none; width: 100%; height: ${props.height}; `}
></iframe>
);
};
},
});