161 lines
5.2 KiB
Smarty
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
defineComponent,
ref,
reactive,
watch,
computed,
onBeforeUnmount,
onMounted,
} from "vue";
import { loadMicroApp } from "{{{QIANKUN}}}";
import {mergeWith} from "{{{LODASH_ES}}}";
// eslint-disable-next-line import/extensions
import { getMasterOptions } from "./masterOptions";
function unmountMicroApp(microApp) {
if (!microApp) {
return;
}
const status = microApp.getStatus();
if (status === 'MOUNTED') {
microApp.unmount();
}
}
export const MicroApp = defineComponent({
props: {
name: {
type: String,
required: true
},
settings: Object,
props: Object,
lifeCycles: Object
},
setup(props, { attrs }) {
const {
masterHistoryType,
apps = [],
lifeCycles: globalLifeCycles,
...globalSettings
} = getMasterOptions();
//
const containerRef = ref(null);
const microAppRef = ref();
const updatingPromiseRef = ref();
const updatingTimestampRef = ref(Date.now());
const appConfigRef = computed(() => {
const appConfig = apps.find((app) => app.name === props.name);
if (!appConfig) {
throw new Error(
`[@fesjs/plugin-qiankun]: Can not find the configuration of ${props.name} app!`
);
}
return appConfig;
});
const propsFromConfigRef = computed(() => {
const appConfig = appConfigRef.value;
if (appConfig) {
return appConfig.props;
}
return {};
});
const propsConfigRef = computed(() => {
return {
...propsFromConfigRef.value,
...props.props,
...attrs
};
});
// name变化时才重新加载新的子应用
const loadApp = () => {
const appConfig = appConfigRef.value;
const { name, entry } = appConfig;
//
microAppRef.value = loadMicroApp(
{
//
name: `${name}_${Date.now()}`,
entry: entry,
container: containerRef.value,
props: {...propsConfigRef.value}
},
{
...globalSettings,
...(props.settings || {})
},
mergeWith(
{},
globalLifeCycles || {},
props.lifeCycles || {},
(v1, v2) => concat(v1 ?? [], v2 ?? [])
)
);
};
// update子应用
const updateApp = () => {
const microApp = microAppRef.value;
if (microApp) {
if (!updatingPromiseRef.value) {
// updatingPromiseRef microApp.mountPromise mount
updatingPromiseRef.value = microApp.mountPromise;
}
// microApp.update
updatingPromiseRef.value = updatingPromiseRef.value.then(
() => {
const canUpdate = (app) =>
app?.update && app.getStatus() === 'MOUNTED';
if (canUpdate(microApp)) {
if (process.env.NODE_ENV === 'development') {
if (
Date.now() -
updatingTimestampRef.value <
200
) {
console.warn(
`[@fesjs/plugin-qiankun] It seems like microApp ${props.name} is updating too many times in a short time(200ms), you may need to do some optimization to avoid the unnecessary re-rendering.`
);
}
console.info(
`[@fesjs/plugin-qiankun] MicroApp ${props.name} is updating with props: `,
props
);
updatingTimestampRef.value = Date.now();
}
// microApp.update
return microApp.update({...propsConfigRef.value});
}
}
);
}
};
onMounted(() => {
loadApp();
});
onBeforeUnmount(() => {
unmountMicroApp(microAppRef.value);
});
watch(appConfigRef, () => {
unmountMicroApp(microAppRef.value);
loadApp();
});
watch(propsConfigRef, () => {
updateApp();
});
return () => <div ref={containerRef}></div>;
}
});