mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-16 06:42:53 +00:00
feat: demo schema & complex children type
This commit is contained in:
parent
0210c4d9ba
commit
a5ee6bd558
@ -1,276 +0,0 @@
|
|||||||
import { IBasicSchema } from '@/types';
|
|
||||||
|
|
||||||
const demoData: IBasicSchema = {
|
|
||||||
version: '1.0.0',
|
|
||||||
componentsMap: [
|
|
||||||
{
|
|
||||||
componentName: 'Button',
|
|
||||||
package: '@alifd/next',
|
|
||||||
version: '1.19.4',
|
|
||||||
destructuring: true,
|
|
||||||
exportName: 'Select',
|
|
||||||
subName: 'Button',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
utils: [
|
|
||||||
{
|
|
||||||
name: 'clone',
|
|
||||||
type: 'npm',
|
|
||||||
content: {
|
|
||||||
package: 'lodash',
|
|
||||||
version: '0.0.1',
|
|
||||||
exportName: 'clone',
|
|
||||||
subName: '',
|
|
||||||
destructuring: false,
|
|
||||||
main: '/lib/clone',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'moment',
|
|
||||||
type: 'npm',
|
|
||||||
content: {
|
|
||||||
package: '@alife/next',
|
|
||||||
version: '0.0.1',
|
|
||||||
exportName: 'Moment',
|
|
||||||
subName: '',
|
|
||||||
destructuring: true,
|
|
||||||
main: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
componentsTree: [
|
|
||||||
{
|
|
||||||
componentName: 'Page',
|
|
||||||
fileName: 'loopDemo',
|
|
||||||
props: {},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
componentName: 'Html',
|
|
||||||
props: {
|
|
||||||
html:
|
|
||||||
'1.选中Col组件,在右侧“数据”面板,设置循环数据;<br/>\n2.给Col组件内的子组件文本内容,绑定对应的数据变量;this.item获取当前循环数据,this.index获取当前循环序号',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Row',
|
|
||||||
props: {
|
|
||||||
style: {
|
|
||||||
paddingTop: 30,
|
|
||||||
paddingRight: 30,
|
|
||||||
paddingBottom: 30,
|
|
||||||
paddingLeft: 30,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
componentName: 'Col',
|
|
||||||
props: {},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
props: {
|
|
||||||
style: {
|
|
||||||
display: 'block',
|
|
||||||
marginBottom: 8,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
fontSize: 14,
|
|
||||||
lineHeight: '32px',
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: 'this.item.title',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
props: {
|
|
||||||
style: {
|
|
||||||
display: 'block',
|
|
||||||
marginBottom: 12,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
fontSize: 16,
|
|
||||||
color: '#65aa14',
|
|
||||||
lineHeight: '12px',
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: 'this.item.num',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
props: {
|
|
||||||
style: {
|
|
||||||
display: 'block',
|
|
||||||
color: '#9b9b9b',
|
|
||||||
},
|
|
||||||
text: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: 'this.item.description',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
loop: [
|
|
||||||
{
|
|
||||||
title: '活跃UV',
|
|
||||||
num: 2783,
|
|
||||||
description: '小二:外包商家:12',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '活跃PV',
|
|
||||||
num: 17382,
|
|
||||||
description: '小二外包商家123',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '不活跃页面数',
|
|
||||||
num: 36,
|
|
||||||
description: '占总页面数比例 30%',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '人均使用时长',
|
|
||||||
num: 788,
|
|
||||||
description: '人均使用频次',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '新增用户数',
|
|
||||||
num: 14,
|
|
||||||
description: '小二:外包:商家 1:1:1',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Col',
|
|
||||||
props: {},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
componentName: 'Text',
|
|
||||||
props: {
|
|
||||||
style: {
|
|
||||||
display: 'block',
|
|
||||||
marginBottom: 8,
|
|
||||||
fontWeight: 'bold',
|
|
||||||
fontSize: '14px',
|
|
||||||
lineHeight: '32px',
|
|
||||||
},
|
|
||||||
text: '更多用户数据分析',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Button',
|
|
||||||
props: {
|
|
||||||
type: 'primary',
|
|
||||||
style: {
|
|
||||||
margin: '0 5px 0 5px',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
children: '查看详情',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
componentName: 'Table',
|
|
||||||
props: {
|
|
||||||
hasBorder: true,
|
|
||||||
hasHeader: true,
|
|
||||||
dataSource: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: 'a1',
|
|
||||||
age: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'a2',
|
|
||||||
age: 2,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: 'a3',
|
|
||||||
age: 3,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
name: 'a4',
|
|
||||||
age: 4,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
componentName: 'TableColumn',
|
|
||||||
props: {
|
|
||||||
title: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: 'this.item.title',
|
|
||||||
},
|
|
||||||
dataIndex: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: 'this.item.dataIndex',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
loop: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: 'this.state.columns',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
state: {
|
|
||||||
dataSource: [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
name: 'a1',
|
|
||||||
age: 21,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
name: 'a2',
|
|
||||||
age: 22,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
name: 'a3',
|
|
||||||
age: 23,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
name: 'a4',
|
|
||||||
age: 24,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
columns: [
|
|
||||||
{
|
|
||||||
title: 'ID',
|
|
||||||
dataIndex: 'id',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '姓名',
|
|
||||||
dataIndex: 'name',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '年龄',
|
|
||||||
dataIndex: 'age',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
i18n: {
|
|
||||||
'zh-CN': {
|
|
||||||
'i18n-jwg27yo4': '你好',
|
|
||||||
'i18n-jwg27yo3': '中国',
|
|
||||||
},
|
|
||||||
'en-US': {
|
|
||||||
'i18n-jwg27yo4': 'Hello',
|
|
||||||
'i18n-jwg27yo3': 'China',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
export default demoData;
|
|
||||||
@ -1,136 +1,7 @@
|
|||||||
import { IProjectSchema, IResultDir, IResultFile } from '@/types';
|
import { IResultDir, IResultFile } from '@/types';
|
||||||
|
|
||||||
import CodeGenerator from '@/index';
|
import CodeGenerator from '@/index';
|
||||||
|
import demoSchema from './simpleDemo';
|
||||||
const schema: IProjectSchema = {
|
|
||||||
version: '1.0.0',
|
|
||||||
componentsMap: [
|
|
||||||
{
|
|
||||||
componentName: 'Button',
|
|
||||||
package: 'alife/next',
|
|
||||||
version: '1.0.0',
|
|
||||||
destructuring: true,
|
|
||||||
exportName: 'Select',
|
|
||||||
subName: 'Button',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
componentsTree: [
|
|
||||||
{
|
|
||||||
componentName: 'Page',
|
|
||||||
fileName: 'Page1',
|
|
||||||
props: {},
|
|
||||||
css: 'body {font-size: 12px;} .table { width: 100px;}',
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
componentName: 'Div',
|
|
||||||
props: {
|
|
||||||
className: '',
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
{
|
|
||||||
componentName: 'Button',
|
|
||||||
props: {
|
|
||||||
prop1: 1234,
|
|
||||||
prop2: [
|
|
||||||
{
|
|
||||||
label: '选项1',
|
|
||||||
value: 1,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '选项2',
|
|
||||||
value: 2,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
prop3: [
|
|
||||||
{
|
|
||||||
name: 'myName',
|
|
||||||
rule: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: '/w+/i',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
valueBind: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: 'this.state.user.name',
|
|
||||||
},
|
|
||||||
onClick: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: 'function(e) { console.log(e.target.innerText) }',
|
|
||||||
},
|
|
||||||
onClick2: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: 'this.submit',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
utils: [
|
|
||||||
{
|
|
||||||
name: 'clone',
|
|
||||||
type: 'npm',
|
|
||||||
content: {
|
|
||||||
package: 'lodash',
|
|
||||||
version: '0.0.1',
|
|
||||||
exportName: 'clone',
|
|
||||||
subName: '',
|
|
||||||
destructuring: false,
|
|
||||||
main: '/lib/clone',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'beforeRequestHandler',
|
|
||||||
type: 'function',
|
|
||||||
content: {
|
|
||||||
type: 'JSExpression',
|
|
||||||
value: 'function(){\n ... \n}',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
constants: {
|
|
||||||
ENV: 'prod',
|
|
||||||
DOMAIN: 'xxx.alibaba-inc.com',
|
|
||||||
},
|
|
||||||
css: 'body {font-size: 12px;} .table { width: 100px;}',
|
|
||||||
config: {
|
|
||||||
sdkVersion: '1.0.3',
|
|
||||||
historyMode: 'hash',
|
|
||||||
targetRootID: 'J_Container',
|
|
||||||
layout: {
|
|
||||||
componentName: 'BasicLayout',
|
|
||||||
props: {
|
|
||||||
logo: '...',
|
|
||||||
name: '测试网站',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
theme: {
|
|
||||||
package: '@alife/theme-fusion',
|
|
||||||
version: '^0.1.0',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
meta: {
|
|
||||||
name: 'demo应用',
|
|
||||||
git_group: 'appGroup',
|
|
||||||
project_name: 'app_demo',
|
|
||||||
description: '这是一个测试应用',
|
|
||||||
spma: 'spa23d',
|
|
||||||
creator: '月飞',
|
|
||||||
},
|
|
||||||
i18n: {
|
|
||||||
'zh-CN': {
|
|
||||||
i18nJwg27yo4: '你好',
|
|
||||||
i18nJwg27yo3: '中国',
|
|
||||||
},
|
|
||||||
'en-US': {
|
|
||||||
i18nJwg27yo4: 'Hello',
|
|
||||||
i18nJwg27yo3: 'China',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function flatFiles(rootName: string | null, dir: IResultDir): IResultFile[] {
|
function flatFiles(rootName: string | null, dir: IResultDir): IResultFile[] {
|
||||||
const dirRoot: string = rootName ? `${rootName}/${dir.name}` : dir.name;
|
const dirRoot: string = rootName ? `${rootName}/${dir.name}` : dir.name;
|
||||||
@ -148,7 +19,7 @@ function flatFiles(rootName: string | null, dir: IResultDir): IResultFile[] {
|
|||||||
function main() {
|
function main() {
|
||||||
const createIceJsProjectBuilder = CodeGenerator.solutions.icejs;
|
const createIceJsProjectBuilder = CodeGenerator.solutions.icejs;
|
||||||
const builder = createIceJsProjectBuilder();
|
const builder = createIceJsProjectBuilder();
|
||||||
builder.generateProject(schema).then(result => {
|
builder.generateProject(demoSchema).then(result => {
|
||||||
const files = flatFiles('.', result);
|
const files = flatFiles('.', result);
|
||||||
files.forEach(file => {
|
files.forEach(file => {
|
||||||
console.log(`========== ${file.name} Start ==========`);
|
console.log(`========== ${file.name} Start ==========`);
|
||||||
|
|||||||
230
packages/code-generator/src/demo/simpleDemo.ts
Normal file
230
packages/code-generator/src/demo/simpleDemo.ts
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
import { IProjectSchema } from '@/types';
|
||||||
|
|
||||||
|
const demoData: IProjectSchema = {
|
||||||
|
version: '1.0.0',
|
||||||
|
componentsMap: [
|
||||||
|
{
|
||||||
|
componentName: 'Button',
|
||||||
|
package: '@alifd/next',
|
||||||
|
version: '1.19.18',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Button',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Button.Group',
|
||||||
|
package: '@alifd/next',
|
||||||
|
version: '1.19.18',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Button',
|
||||||
|
subName: 'Group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Input',
|
||||||
|
package: '@alifd/next',
|
||||||
|
version: '1.19.18',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Input',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Form',
|
||||||
|
package: '@alifd/next',
|
||||||
|
version: '1.19.18',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Form',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Form.Item',
|
||||||
|
package: '@alifd/next',
|
||||||
|
version: '1.19.18',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Form',
|
||||||
|
subName: 'Item',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'NumberPicker',
|
||||||
|
package: '@alifd/next',
|
||||||
|
version: '1.19.18',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'NumberPicker',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Select',
|
||||||
|
package: '@alifd/next',
|
||||||
|
version: '1.19.18',
|
||||||
|
destructuring: true,
|
||||||
|
exportName: 'Select',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
componentsTree: [
|
||||||
|
{
|
||||||
|
componentName: 'Page',
|
||||||
|
id: 'node$1',
|
||||||
|
props: {
|
||||||
|
ref: 'outterView',
|
||||||
|
autoLoading: true,
|
||||||
|
},
|
||||||
|
fileName: 'test',
|
||||||
|
state: {
|
||||||
|
text: 'outter',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Form',
|
||||||
|
id: 'node$2',
|
||||||
|
props: {
|
||||||
|
labelCol: 4,
|
||||||
|
style: {},
|
||||||
|
ref: 'testForm',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Form.Item',
|
||||||
|
id: 'node$3',
|
||||||
|
props: {
|
||||||
|
label: '姓名:',
|
||||||
|
name: 'name',
|
||||||
|
initValue: '李雷',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Input',
|
||||||
|
id: 'node$4',
|
||||||
|
props: {
|
||||||
|
placeholder: '请输入',
|
||||||
|
size: 'medium',
|
||||||
|
style: {
|
||||||
|
width: 320,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Form.Item',
|
||||||
|
id: 'node$5',
|
||||||
|
props: {
|
||||||
|
label: '年龄:',
|
||||||
|
name: 'age',
|
||||||
|
initValue: '22',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'NumberPicker',
|
||||||
|
id: 'node$6',
|
||||||
|
props: {
|
||||||
|
size: 'medium',
|
||||||
|
type: 'normal',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Form.Item',
|
||||||
|
id: 'node$7',
|
||||||
|
props: {
|
||||||
|
label: '职业:',
|
||||||
|
name: 'profession',
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Select',
|
||||||
|
id: 'node$8',
|
||||||
|
props: {
|
||||||
|
dataSource: [
|
||||||
|
{
|
||||||
|
label: '教师',
|
||||||
|
value: 't',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '医生',
|
||||||
|
value: 'd',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '歌手',
|
||||||
|
value: 's',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Div',
|
||||||
|
id: 'node$9',
|
||||||
|
props: {
|
||||||
|
style: {
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Button.Group',
|
||||||
|
id: 'node$a',
|
||||||
|
props: {},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
componentName: 'Button',
|
||||||
|
id: 'node$b',
|
||||||
|
props: {
|
||||||
|
type: 'primary',
|
||||||
|
style: {
|
||||||
|
margin: '0 5px 0 5px',
|
||||||
|
},
|
||||||
|
htmlType: 'submit',
|
||||||
|
},
|
||||||
|
children: ['提交'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
componentName: 'Button',
|
||||||
|
id: 'node$d',
|
||||||
|
props: {
|
||||||
|
type: 'normal',
|
||||||
|
style: {
|
||||||
|
margin: '0 5px 0 5px',
|
||||||
|
},
|
||||||
|
htmlType: 'reset',
|
||||||
|
},
|
||||||
|
children: ['重置'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
constants: {
|
||||||
|
ENV: 'prod',
|
||||||
|
DOMAIN: 'xxx.alibaba-inc.com',
|
||||||
|
},
|
||||||
|
css: 'body {font-size: 12px;} .table { width: 100px;}',
|
||||||
|
config: {
|
||||||
|
sdkVersion: '1.0.3',
|
||||||
|
historyMode: 'hash',
|
||||||
|
targetRootID: 'J_Container',
|
||||||
|
layout: {
|
||||||
|
componentName: 'BasicLayout',
|
||||||
|
props: {
|
||||||
|
logo: '...',
|
||||||
|
name: '测试网站',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
package: '@alife/theme-fusion',
|
||||||
|
version: '^0.1.0',
|
||||||
|
primary: '#ff9966',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
name: 'demo应用',
|
||||||
|
git_group: 'appGroup',
|
||||||
|
project_name: 'app_demo',
|
||||||
|
description: '这是一个测试应用',
|
||||||
|
spma: 'spa23d',
|
||||||
|
creator: '月飞',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default demoData;
|
||||||
@ -5,9 +5,12 @@
|
|||||||
|
|
||||||
import { SUPPORT_SCHEMA_VERSION_LIST } from '../const';
|
import { SUPPORT_SCHEMA_VERSION_LIST } from '../const';
|
||||||
|
|
||||||
|
import { handleChildren } from '../utils/children';
|
||||||
import { uniqueArray } from '../utils/common';
|
import { uniqueArray } from '../utils/common';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
ChildNodeItem,
|
||||||
|
ChildNodeType,
|
||||||
CodeGeneratorError,
|
CodeGeneratorError,
|
||||||
CompatibilityError,
|
CompatibilityError,
|
||||||
DependencyType,
|
DependencyType,
|
||||||
@ -169,12 +172,10 @@ class SchemaParser implements ISchemaParser {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getComponentNames(list: IComponentNodeItem[]): string[] {
|
public getComponentNames(children: ChildNodeType): string[] {
|
||||||
const names = list.map(i => i.componentName);
|
return handleChildren<string>(children, {
|
||||||
const namesForward = list
|
node: (i: IComponentNodeItem) => [i.componentName],
|
||||||
.map(i => this.getComponentNames(i.children || []))
|
});
|
||||||
.reduce((p, c) => p.concat(c), []);
|
|
||||||
return names.concat(namesForward);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import { REACT_CHUNK_NAME } from './const';
|
|
||||||
|
|
||||||
import { generateCompositeType } from '../../utils/compositeType';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BuilderComponentPlugin,
|
BuilderComponentPlugin,
|
||||||
|
ChildNodeItem,
|
||||||
|
ChildNodeType,
|
||||||
ChunkType,
|
ChunkType,
|
||||||
FileType,
|
FileType,
|
||||||
ICodeStruct,
|
ICodeStruct,
|
||||||
@ -13,6 +11,10 @@ import {
|
|||||||
IJSExpression,
|
IJSExpression,
|
||||||
} from '../../../types';
|
} from '../../../types';
|
||||||
|
|
||||||
|
import { handleChildren } from '@/utils/children';
|
||||||
|
import { generateCompositeType } from '../../utils/compositeType';
|
||||||
|
import { REACT_CHUNK_NAME } from './const';
|
||||||
|
|
||||||
function generateInlineStyle(style: IInlineStyle): string | null {
|
function generateInlineStyle(style: IInlineStyle): string | null {
|
||||||
const attrLines = Object.keys(style).map((cssAttribute: string) => {
|
const attrLines = Object.keys(style).map((cssAttribute: string) => {
|
||||||
const [isString, valueStr] = generateCompositeType(style[cssAttribute]);
|
const [isString, valueStr] = generateCompositeType(style[cssAttribute]);
|
||||||
@ -52,9 +54,9 @@ function generateNode(nodeItem: IComponentNodeItem): string {
|
|||||||
);
|
);
|
||||||
codePieces.push.apply(codePieces, propLines);
|
codePieces.push.apply(codePieces, propLines);
|
||||||
|
|
||||||
if (nodeItem.children && nodeItem.children.length > 0) {
|
if (nodeItem.children && (nodeItem.children as unknown[]).length > 0) {
|
||||||
codePieces.push('>');
|
codePieces.push('>');
|
||||||
const childrenLines = nodeItem.children.map(child => generateNode(child));
|
const childrenLines = generateChildren(nodeItem.children);
|
||||||
codePieces.push.apply(codePieces, childrenLines);
|
codePieces.push.apply(codePieces, childrenLines);
|
||||||
codePieces.push(`</${nodeItem.componentName}>`);
|
codePieces.push(`</${nodeItem.componentName}>`);
|
||||||
} else {
|
} else {
|
||||||
@ -87,6 +89,15 @@ function generateNode(nodeItem: IComponentNodeItem): string {
|
|||||||
return codePieces.join(' ');
|
return codePieces.join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function generateChildren(children: ChildNodeType): string[] {
|
||||||
|
return handleChildren<string>(children, {
|
||||||
|
// TODO: 如果容器直接只有一个 字符串 children 呢?
|
||||||
|
string: (input: string) => [input],
|
||||||
|
expression: (input: IJSExpression) => [`{${input.value}}`],
|
||||||
|
node: (input: IComponentNodeItem) => [generateNode(input)],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||||
const next: ICodeStruct = {
|
const next: ICodeStruct = {
|
||||||
...pre,
|
...pre,
|
||||||
@ -95,14 +106,17 @@ const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
|||||||
const ir = next.ir as IContainerInfo;
|
const ir = next.ir as IContainerInfo;
|
||||||
|
|
||||||
let jsxContent: string;
|
let jsxContent: string;
|
||||||
if (!ir.children || ir.children.length === 0) {
|
if (!ir.children || (ir.children as unknown[]).length === 0) {
|
||||||
jsxContent = 'null';
|
jsxContent = 'null';
|
||||||
} else if (ir.children.length === 1) {
|
|
||||||
jsxContent = `(${generateNode(ir.children[0])})`;
|
|
||||||
} else {
|
} else {
|
||||||
jsxContent = `(<React.Fragment>${ir.children
|
const childrenCode = generateChildren(ir.children);
|
||||||
.map(child => generateNode(child))
|
if (childrenCode.length === 1) {
|
||||||
.join('')}</React.Fragment>)`;
|
jsxContent = `(${childrenCode[0]})`;
|
||||||
|
} else {
|
||||||
|
jsxContent = `(<React.Fragment>${childrenCode.join(
|
||||||
|
'',
|
||||||
|
)}</React.Fragment>)`;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
next.chunks.push({
|
next.chunks.push({
|
||||||
|
|||||||
@ -8,18 +8,6 @@ import {
|
|||||||
IUtilItem,
|
IUtilItem,
|
||||||
} from './index';
|
} from './index';
|
||||||
|
|
||||||
export interface IPackageJSON {
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
version: string;
|
|
||||||
main?: string;
|
|
||||||
author?: string;
|
|
||||||
license?: string;
|
|
||||||
scripts?: Record<string, string>;
|
|
||||||
dependencies?: Record<string, string>;
|
|
||||||
[key: string]: unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IParseResult {
|
export interface IParseResult {
|
||||||
containers: IContainerInfo[];
|
containers: IContainerInfo[];
|
||||||
globalUtils?: IUtilInfo;
|
globalUtils?: IUtilInfo;
|
||||||
|
|||||||
@ -91,8 +91,8 @@ export interface IInlineStyle {
|
|||||||
[cssAttribute: string]: string | number | IJSExpression;
|
[cssAttribute: string]: string | number | IJSExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChildNodeItem = string | IJSExpression | IComponentNodeItem;
|
export type ChildNodeItem = string | IJSExpression | IComponentNodeItem;
|
||||||
type ChildNodeType = ChildNodeItem | ChildNodeItem[];
|
export type ChildNodeType = ChildNodeItem | ChildNodeItem[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 搭建基础协议 - 单个组件树节点描述
|
* 搭建基础协议 - 单个组件树节点描述
|
||||||
@ -102,6 +102,8 @@ type ChildNodeType = ChildNodeItem | ChildNodeItem[];
|
|||||||
* @interface IComponentNodeItem
|
* @interface IComponentNodeItem
|
||||||
*/
|
*/
|
||||||
export interface IComponentNodeItem {
|
export interface IComponentNodeItem {
|
||||||
|
// TODO: 不需要 id 字段,暂时简单兼容
|
||||||
|
id?: string;
|
||||||
componentName: string; // 组件名称 必填、首字母大写
|
componentName: string; // 组件名称 必填、首字母大写
|
||||||
props: {
|
props: {
|
||||||
className?: string; // 组件样式类名
|
className?: string; // 组件样式类名
|
||||||
@ -170,7 +172,7 @@ export interface IDataSource {
|
|||||||
* 返回值:数据对象data,将会在渲染引擎和schemaToCode中通过调用this.setState(...)将返回的数据对象生效到state中;
|
* 返回值:数据对象data,将会在渲染引擎和schemaToCode中通过调用this.setState(...)将返回的数据对象生效到state中;
|
||||||
* 支持返回一个Promise,通过resolve(返回数据),常用于串型发送请求场景,配合this.dataSourceMap[oneRequest.id].load()使用;
|
* 支持返回一个Promise,通过resolve(返回数据),常用于串型发送请求场景,配合this.dataSourceMap[oneRequest.id].load()使用;
|
||||||
*/
|
*/
|
||||||
dataHandler: IJSExpression;
|
dataHandler?: IJSExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -182,7 +184,7 @@ export interface IDataSource {
|
|||||||
export interface IDataSourceConfig {
|
export interface IDataSourceConfig {
|
||||||
id: string; // 数据请求ID标识
|
id: string; // 数据请求ID标识
|
||||||
isInit: boolean; // 是否为初始数据 支持表达式 值为true时,将在组件初始化渲染时自动发送当前数据请求
|
isInit: boolean; // 是否为初始数据 支持表达式 值为true时,将在组件初始化渲染时自动发送当前数据请求
|
||||||
type: 'fetch' | 'mtop' | 'jsonp' | 'custom'; // 数据请求类型
|
type: 'fetch' | 'mtop' | 'jsonp' | 'custom' | 'doServer'; // 数据请求类型
|
||||||
requestHandler?: IJSExpression; // 自定义扩展的外部请求处理器 仅type='custom'时生效
|
requestHandler?: IJSExpression; // 自定义扩展的外部请求处理器 仅type='custom'时生效
|
||||||
options?: IFetchOptions; // 请求参数配置 每种请求类型对应不同参数
|
options?: IFetchOptions; // 请求参数配置 每种请求类型对应不同参数
|
||||||
dataHandler?: IJSExpression; // 数据结果处理函数,形如:(data, err) => Object
|
dataHandler?: IJSExpression; // 数据结果处理函数,形如:(data, err) => Object
|
||||||
@ -201,8 +203,8 @@ export interface IFetchOptions {
|
|||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
method: 'GET' | 'POST';
|
method: 'GET' | 'POST';
|
||||||
isCors: boolean; // 是否支持跨域,对应credentials = 'include'
|
isCors?: boolean; // 是否支持跨域,对应credentials = 'include'
|
||||||
timeout: number; // 超时时长
|
timeout?: number; // 超时时长
|
||||||
headers?: {
|
headers?: {
|
||||||
// 自定义请求头
|
// 自定义请求头
|
||||||
[key: string]: string;
|
[key: string]: string;
|
||||||
|
|||||||
35
packages/code-generator/src/utils/children.ts
Normal file
35
packages/code-generator/src/utils/children.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import {
|
||||||
|
ChildNodeItem,
|
||||||
|
ChildNodeType,
|
||||||
|
IComponentNodeItem,
|
||||||
|
IJSExpression,
|
||||||
|
} from '@/types';
|
||||||
|
|
||||||
|
// tslint:disable-next-line: no-empty
|
||||||
|
const noop = () => [];
|
||||||
|
|
||||||
|
export function handleChildren<T>(
|
||||||
|
children: ChildNodeType,
|
||||||
|
handlers: {
|
||||||
|
string?: (input: string) => T[];
|
||||||
|
expression?: (input: IJSExpression) => T[];
|
||||||
|
node?: (input: IComponentNodeItem) => T[];
|
||||||
|
common?: (input: unknown) => T[];
|
||||||
|
},
|
||||||
|
): T[] {
|
||||||
|
if (Array.isArray(children)) {
|
||||||
|
const list: ChildNodeItem[] = children as ChildNodeItem[];
|
||||||
|
return list
|
||||||
|
.map(child => handleChildren(child, handlers))
|
||||||
|
.reduce((p, c) => p.concat(c), []);
|
||||||
|
} else if (typeof children === 'string') {
|
||||||
|
const handler = handlers.string || handlers.common || noop;
|
||||||
|
return handler(children as string);
|
||||||
|
} else if ((children as IJSExpression).type === 'JSExpression') {
|
||||||
|
const handler = handlers.expression || handlers.common || noop;
|
||||||
|
return handler(children as IJSExpression);
|
||||||
|
} else {
|
||||||
|
const handler = handlers.node || handlers.common || noop;
|
||||||
|
return handler(children as IComponentNodeItem);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user