mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2025-12-13 04:03:07 +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';
|
||||
|
||||
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',
|
||||
},
|
||||
},
|
||||
};
|
||||
import demoSchema from './simpleDemo';
|
||||
|
||||
function flatFiles(rootName: string | null, dir: IResultDir): IResultFile[] {
|
||||
const dirRoot: string = rootName ? `${rootName}/${dir.name}` : dir.name;
|
||||
@ -148,7 +19,7 @@ function flatFiles(rootName: string | null, dir: IResultDir): IResultFile[] {
|
||||
function main() {
|
||||
const createIceJsProjectBuilder = CodeGenerator.solutions.icejs;
|
||||
const builder = createIceJsProjectBuilder();
|
||||
builder.generateProject(schema).then(result => {
|
||||
builder.generateProject(demoSchema).then(result => {
|
||||
const files = flatFiles('.', result);
|
||||
files.forEach(file => {
|
||||
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 { handleChildren } from '../utils/children';
|
||||
import { uniqueArray } from '../utils/common';
|
||||
|
||||
import {
|
||||
ChildNodeItem,
|
||||
ChildNodeType,
|
||||
CodeGeneratorError,
|
||||
CompatibilityError,
|
||||
DependencyType,
|
||||
@ -169,12 +172,10 @@ class SchemaParser implements ISchemaParser {
|
||||
};
|
||||
}
|
||||
|
||||
public getComponentNames(list: IComponentNodeItem[]): string[] {
|
||||
const names = list.map(i => i.componentName);
|
||||
const namesForward = list
|
||||
.map(i => this.getComponentNames(i.children || []))
|
||||
.reduce((p, c) => p.concat(c), []);
|
||||
return names.concat(namesForward);
|
||||
public getComponentNames(children: ChildNodeType): string[] {
|
||||
return handleChildren<string>(children, {
|
||||
node: (i: IComponentNodeItem) => [i.componentName],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
import { REACT_CHUNK_NAME } from './const';
|
||||
|
||||
import { generateCompositeType } from '../../utils/compositeType';
|
||||
|
||||
import {
|
||||
BuilderComponentPlugin,
|
||||
ChildNodeItem,
|
||||
ChildNodeType,
|
||||
ChunkType,
|
||||
FileType,
|
||||
ICodeStruct,
|
||||
@ -13,6 +11,10 @@ import {
|
||||
IJSExpression,
|
||||
} from '../../../types';
|
||||
|
||||
import { handleChildren } from '@/utils/children';
|
||||
import { generateCompositeType } from '../../utils/compositeType';
|
||||
import { REACT_CHUNK_NAME } from './const';
|
||||
|
||||
function generateInlineStyle(style: IInlineStyle): string | null {
|
||||
const attrLines = Object.keys(style).map((cssAttribute: string) => {
|
||||
const [isString, valueStr] = generateCompositeType(style[cssAttribute]);
|
||||
@ -52,9 +54,9 @@ function generateNode(nodeItem: IComponentNodeItem): string {
|
||||
);
|
||||
codePieces.push.apply(codePieces, propLines);
|
||||
|
||||
if (nodeItem.children && nodeItem.children.length > 0) {
|
||||
if (nodeItem.children && (nodeItem.children as unknown[]).length > 0) {
|
||||
codePieces.push('>');
|
||||
const childrenLines = nodeItem.children.map(child => generateNode(child));
|
||||
const childrenLines = generateChildren(nodeItem.children);
|
||||
codePieces.push.apply(codePieces, childrenLines);
|
||||
codePieces.push(`</${nodeItem.componentName}>`);
|
||||
} else {
|
||||
@ -87,6 +89,15 @@ function generateNode(nodeItem: IComponentNodeItem): string {
|
||||
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 next: ICodeStruct = {
|
||||
...pre,
|
||||
@ -95,14 +106,17 @@ const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||
const ir = next.ir as IContainerInfo;
|
||||
|
||||
let jsxContent: string;
|
||||
if (!ir.children || ir.children.length === 0) {
|
||||
if (!ir.children || (ir.children as unknown[]).length === 0) {
|
||||
jsxContent = 'null';
|
||||
} else if (ir.children.length === 1) {
|
||||
jsxContent = `(${generateNode(ir.children[0])})`;
|
||||
} else {
|
||||
jsxContent = `(<React.Fragment>${ir.children
|
||||
.map(child => generateNode(child))
|
||||
.join('')}</React.Fragment>)`;
|
||||
const childrenCode = generateChildren(ir.children);
|
||||
if (childrenCode.length === 1) {
|
||||
jsxContent = `(${childrenCode[0]})`;
|
||||
} else {
|
||||
jsxContent = `(<React.Fragment>${childrenCode.join(
|
||||
'',
|
||||
)}</React.Fragment>)`;
|
||||
}
|
||||
}
|
||||
|
||||
next.chunks.push({
|
||||
|
||||
@ -8,18 +8,6 @@ import {
|
||||
IUtilItem,
|
||||
} 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 {
|
||||
containers: IContainerInfo[];
|
||||
globalUtils?: IUtilInfo;
|
||||
|
||||
@ -91,8 +91,8 @@ export interface IInlineStyle {
|
||||
[cssAttribute: string]: string | number | IJSExpression;
|
||||
}
|
||||
|
||||
type ChildNodeItem = string | IJSExpression | IComponentNodeItem;
|
||||
type ChildNodeType = ChildNodeItem | ChildNodeItem[];
|
||||
export type ChildNodeItem = string | IJSExpression | IComponentNodeItem;
|
||||
export type ChildNodeType = ChildNodeItem | ChildNodeItem[];
|
||||
|
||||
/**
|
||||
* 搭建基础协议 - 单个组件树节点描述
|
||||
@ -102,6 +102,8 @@ type ChildNodeType = ChildNodeItem | ChildNodeItem[];
|
||||
* @interface IComponentNodeItem
|
||||
*/
|
||||
export interface IComponentNodeItem {
|
||||
// TODO: 不需要 id 字段,暂时简单兼容
|
||||
id?: string;
|
||||
componentName: string; // 组件名称 必填、首字母大写
|
||||
props: {
|
||||
className?: string; // 组件样式类名
|
||||
@ -170,7 +172,7 @@ export interface IDataSource {
|
||||
* 返回值:数据对象data,将会在渲染引擎和schemaToCode中通过调用this.setState(...)将返回的数据对象生效到state中;
|
||||
* 支持返回一个Promise,通过resolve(返回数据),常用于串型发送请求场景,配合this.dataSourceMap[oneRequest.id].load()使用;
|
||||
*/
|
||||
dataHandler: IJSExpression;
|
||||
dataHandler?: IJSExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -182,7 +184,7 @@ export interface IDataSource {
|
||||
export interface IDataSourceConfig {
|
||||
id: string; // 数据请求ID标识
|
||||
isInit: boolean; // 是否为初始数据 支持表达式 值为true时,将在组件初始化渲染时自动发送当前数据请求
|
||||
type: 'fetch' | 'mtop' | 'jsonp' | 'custom'; // 数据请求类型
|
||||
type: 'fetch' | 'mtop' | 'jsonp' | 'custom' | 'doServer'; // 数据请求类型
|
||||
requestHandler?: IJSExpression; // 自定义扩展的外部请求处理器 仅type='custom'时生效
|
||||
options?: IFetchOptions; // 请求参数配置 每种请求类型对应不同参数
|
||||
dataHandler?: IJSExpression; // 数据结果处理函数,形如:(data, err) => Object
|
||||
@ -201,8 +203,8 @@ export interface IFetchOptions {
|
||||
[key: string]: any;
|
||||
};
|
||||
method: 'GET' | 'POST';
|
||||
isCors: boolean; // 是否支持跨域,对应credentials = 'include'
|
||||
timeout: number; // 超时时长
|
||||
isCors?: boolean; // 是否支持跨域,对应credentials = 'include'
|
||||
timeout?: number; // 超时时长
|
||||
headers?: {
|
||||
// 自定义请求头
|
||||
[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