2025-12-09 17:20:07 +08:00

91 lines
2.0 KiB
Vue

<template>
<component
:is="containerComponent"
:class="className"
:style="style"
:data-tmagic-id="config.id"
:config="{ ...config, [IS_DSL_NODE_KEY]: false }"
></component>
</template>
<script lang="ts" setup>
import { inject, nextTick, watch } from 'vue';
import type TMagicApp from '@tmagic/core';
import { asyncLoadCss, asyncLoadJs, IS_DSL_NODE_KEY, type MPage } from '@tmagic/core';
import { useComponent, useComponentStatus, useNode } from '@tmagic/vue-runtime-help';
const createCss = (config: MPage) => {
if (config.cssFile) {
asyncLoadCss(config.cssFile);
}
if (Array.isArray(config.cssFiles)) {
config.cssFiles.map((file) => asyncLoadCss(file.url));
}
if (config.css) {
const style = window.document.createElement('style');
style.innerHTML = config.css;
window.document.head.appendChild(style);
}
};
const createJs = (config: MPage) => {
if (Array.isArray(config.jsFiles)) {
config.jsFiles.map((file) => asyncLoadJs(file.url));
}
};
defineOptions({
name: 'tmagic-page',
});
const props = withDefaults(
defineProps<{
config: MPage;
model?: Record<string, any>;
}>(),
{
model: () => ({}),
},
);
const app = inject<TMagicApp>('app');
if (app?.jsEngine === 'browser') {
createCss(props.config);
createJs(props.config);
}
const containerComponent = useComponent({ componentType: 'container', app });
const { style, className } = useComponentStatus(props);
const refresh = () => {
window.location.reload();
};
watch(
() => props.config,
async (config, preConfig) => {
const node = useNode({ config: { ...config, [IS_DSL_NODE_KEY]: true } }, app);
if (config.id !== preConfig?.id) {
node?.setInstance({ config: props.config, refresh });
node?.emit('created');
}
await nextTick();
if (config.id !== preConfig?.id) {
node?.emit('mounted');
const preNode = useNode({ config: { ...preConfig, [IS_DSL_NODE_KEY]: true } }, app);
preNode?.emit('destroy');
}
},
{
immediate: true,
},
);
</script>