前言
用schema data快速生成页面
架构思路
由容器组件组装schema 数据,透传到SchemaBox解析数据,则有对应数据获取UI组件到内容区展示,则得到最终用户界面
编辑切换为居中
添加图片注释,不超过 140 字(可选)
代码区
1、schema data
const demoName = {
type:'input', // type判别UI组件,input表示输入框
name:'demoName', // name 数据key
title: '实例名称'
};
export const demoSchema = {
type: 'object', // type 判别template模板
properties:{
demoName,
}
}
2、schema 解析
import React from 'react';
import SchemaContainer from './SchemaContainer';
const SchemaBox = (props) =>{
const { schema, children } = props;
return(
<>
<SchemaContainer schema={schema} />
{children}
</>
)
};
export default SchemaBox;
3、container 容器组件
import React from 'react';
import { getTemplate, getContainer } from './helps';
const SchemaContainer = (props) =>{
const { schema, ...rest } = props;
const { type, ...otherSchema } = schema || {};
const ContainerTemplate = useMemo(() =>getTemplate(type),[type]); // 模板加载
const CommonContainer = useMemo(() => getContainer(type), [type]); // 组件加载
return(
<>
<ContainerTemplate {...rest} schema={otherSchema}>
<CommonContainer schema={otherSchema} />
</ContainerTemplate>
</>
)
};
export default SchemaContainer;
4、helps
import { Input } from '@chakra-ui/react'
import ObjectTemplate from './ObjectTemplate';
import CommonTemplate from './CommonTemplate';
import DefaultTemplate from './DefaultTemplate';
export const getTemplate = (type) =>{
const template = {
'object': ObjectTemplate
}[type] || (['input'].includes(type) && CommonTemplate) || DefaultTemplate;
return template;
};
export const getContainer = (type) =>{
return {
'input': Input;
}[type];
}
5、template
ObjectTemplate
import React from 'react';
import { isEmpty } from 'lodash';
import SchemaContainer from './SchemaContainer';
const ObjectTemplate = (props) =>{
const { schema, name } = props;
const { properties } = schema || {};
if(!properties && isEmpty(properties)) return null;
return Object.keys(properties).map((key) =>{
const propertiesSchema = properties[key];
const propertiesName = name ? `${name}.${key}` : name;
return(
<SchemaContainer key={`${name}-template`} schema={propertiesSchema} name={propertiesName} />
)
})
}
export default ObjectTemplate;
DefaultTemplate
import React from 'react';
import { Box } from '@chakra-ui/react'
const DefaultTemplate = (props) =>{
const { schema, children, ...rest } = props;
const { title, titleStyle = {} } = schema || {};
return(
<Box {..rest}>
{
title && <Box sx={{fontSize: '2rem',...titleStyle}}>{title}</Box>
}
{children}
</Box>
);
}
export default DefaultTemplate;
CommonTemplate
import React, { Children, cloneElement} from 'react';
import { Box } from '@chakra-ui/react'
const CommonTemplate = (props) =>{
const { schema, children, ...rest } = props;
const { title, titleStyle = {}, useCustomHook, useInjectProps } = schema || {};
useCustomHook?.();
const injestProps = useInjectProps?.(props) || {};
return(
<>
{
title && <Box sx={{fontSize: '2rem',...titleStyle}}>{title}</Box>
}
{children && Children.only(children)
? cloneElement(children,
{
...(children?.props),
...rest,
...injestProps,
})
:null
}
<>
);
}
export default CommonTemplate;