118 lines
2.5 KiB
TypeScript
118 lines
2.5 KiB
TypeScript
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<InvokerModName> | 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 <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>
|
||
);
|
||
};
|
||
},
|
||
});
|