166 lines
4.1 KiB
TypeScript
166 lines
4.1 KiB
TypeScript
/*
|
||
* @Author: yehuozhili
|
||
* @Date: 2021-03-14 05:40:37
|
||
* @LastEditors: yehuozhili
|
||
* @LastEditTime: 2022-04-23 18:01:55
|
||
* @FilePath: \dooringx\packages\dooringx-lib\src\components\preview.tsx
|
||
*/
|
||
import Container from './container';
|
||
import React, { ReactElement, ReactNode, useEffect, useState, CSSProperties } from 'react';
|
||
import UserConfig from '../config';
|
||
import { ComponentItemFactory } from '..';
|
||
|
||
export interface PreviewProps {
|
||
config: UserConfig;
|
||
/**
|
||
*
|
||
* loading node
|
||
* @type {ReactNode}
|
||
* @memberof PreviewProps
|
||
*/
|
||
loadText?: ReactNode;
|
||
/**
|
||
*
|
||
* 手动维护状态
|
||
* @type {boolean}
|
||
* @memberof PreviewProps
|
||
*/
|
||
loadingState?: boolean;
|
||
/**
|
||
*
|
||
* 页面链接完后调用
|
||
* @type {Function}
|
||
* @memberof PreviewProps
|
||
*/
|
||
completeFn?: Function;
|
||
/**
|
||
*
|
||
* 预览样式
|
||
* @type {CSSProperties}
|
||
* @memberof PreviewProps
|
||
*/
|
||
previewContainerStyle?: CSSProperties;
|
||
}
|
||
|
||
function Preview(props: PreviewProps): ReactElement {
|
||
const isEdit = props.config.getStore().isEdit();
|
||
/// 这里需要在渲染组件之前必须把所有config加载完成,否则会导致先运行的函数无法运行
|
||
const [loading, setLoading] = useState(true);
|
||
|
||
useEffect(() => {
|
||
const finalFn = () => {
|
||
props.config.created();
|
||
props.config.createdFn.forEach((v) => v());
|
||
setTimeout(() => {
|
||
// 链接数据
|
||
props.config.getDataCenter().initAddToDataMap(props.config.getStore().getData());
|
||
// 链接事件
|
||
props.config
|
||
.getEventCenter()
|
||
.syncEventMap(props.config.getStore().getData(), props.config.getStore());
|
||
|
||
// 设置全局
|
||
const global = props.config.getStore().getData().globalState;
|
||
const bodyColor = global?.bodyColor;
|
||
const title = global?.title;
|
||
if (title) {
|
||
document.title = title;
|
||
}
|
||
if (bodyColor) {
|
||
document.body.style.backgroundColor = bodyColor;
|
||
}
|
||
const customAnimate = global?.customAnimate;
|
||
if (customAnimate && Array.isArray(customAnimate)) {
|
||
// 插入自定义动画
|
||
props.config.animateFactory.fromArrInsertKeyFrame(customAnimate);
|
||
}
|
||
|
||
if (props.completeFn) {
|
||
props.completeFn();
|
||
}
|
||
props.config.beforeOnMounted();
|
||
props.config.beforeOnMountedFn.forEach((v) => v());
|
||
if (props.loadingState === undefined) {
|
||
setLoading(false);
|
||
}
|
||
});
|
||
};
|
||
// 加载 script
|
||
const scripts = props.config.getStore().getData().globalState['script'];
|
||
if (scripts && Array.isArray(scripts) && scripts.length > 0) {
|
||
const fn = async () => {
|
||
const allp = scripts.map((v) => {
|
||
return () =>
|
||
new Promise<number>((res) => {
|
||
const s = document.createElement('script');
|
||
s.src = v;
|
||
document.body.appendChild(s);
|
||
s.onload = () => {
|
||
const item = window[
|
||
props.config.SCRIPTGLOBALNAME as any
|
||
] as unknown as ComponentItemFactory;
|
||
try {
|
||
props.config.registComponent(item);
|
||
} catch {
|
||
console.error('read item fail:', v);
|
||
}
|
||
document.body.removeChild(s);
|
||
res(0);
|
||
};
|
||
});
|
||
});
|
||
const allplen = allp.length;
|
||
for (let i = 0; i < allplen; i++) {
|
||
try {
|
||
await allp[i]();
|
||
} catch {
|
||
console.error('script load fail:', scripts[i]);
|
||
}
|
||
}
|
||
finalFn();
|
||
};
|
||
fn();
|
||
} else {
|
||
finalFn();
|
||
}
|
||
}, [props, props.config]);
|
||
|
||
if (isEdit) {
|
||
// 正常情况不会走这
|
||
const store = props.config.getStore();
|
||
const data = store.getData();
|
||
store.changeModaltoNormal(data);
|
||
return (
|
||
<>
|
||
<Container config={props.config} context="preview" state={store.getData()}></Container>
|
||
</>
|
||
);
|
||
} else {
|
||
const loadingNode = <div>{props.loadText ? props.loadText : 'loading'}</div>;
|
||
const container = (
|
||
<>
|
||
<Container
|
||
config={props.config}
|
||
context="preview"
|
||
state={props.config.getStore().getData()}
|
||
previewContainerStyle={props.previewContainerStyle}
|
||
></Container>
|
||
</>
|
||
);
|
||
if (props.loadingState === undefined) {
|
||
if (loading) {
|
||
return loadingNode;
|
||
} else {
|
||
return container;
|
||
}
|
||
} else {
|
||
if (props.loadingState) {
|
||
return loadingNode;
|
||
} else {
|
||
return container;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
export default Preview;
|