低代码前端架构搭建

152 阅读1分钟

前言

用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;