mirror of
https://github.com/nocobase/nocobase
synced 2024-11-15 23:26:38 +00:00
678b6cef21
* feat: update docs * fix: improve code
5.9 KiB
5.9 KiB
UI Schema 是什么?
一种描述前端组件的协议,基于 Formily Schema 2.0,类 JSON Schema 风格。
interface ISchema {
type: 'void' | 'string' | 'number' | 'object' | 'array';
name?: string;
title?: any;
// 包装器组件
['x-decorator']?: string;
// 包装器组件属性
['x-decorator-props']?: any;
// 组件
['x-component']?: string;
// 组件属性
['x-component-props']?: any;
// 展示状态,默认为 'visible'
['x-display']?: 'none' | 'hidden' | 'visible';
// 组件的子节点,简单使用
['x-content']?: any;
// children 节点 schema
properties?: Record<string, ISchema>;
// 以下仅字段组件时使用
// 字段联动
['x-reactions']?: SchemaReactions;
// 字段 UI 交互模式,默认为 'editable'
['x-pattern']?: 'editable' | 'disabled' | 'readPretty';
// 字段校验
['x-validator']?: Validator;
// 默认数据
default: ?:any;
// 设计器相关
// 设计器组件(工具栏),包括:拖拽移动、插入新节点、修改参数、移除等
['x-designer']?: any;
// 初始化器组件(工具栏),决定当前 schema 内部可以插入什么
['x-initializer']?: any;
}
最简单的组件
所有的原生 html 标签都可以转为 schema 的写法。如:
{
type: 'void',
'x-component': 'h1',
'x-content': 'Hello, world!',
}
JSX 示例
<h1>Hello, world!</h1>
children 组件可以写在 properties 里
{
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
'x-component': 'input',
},
},
}
JSX 等同于
<div className={'form-item'}>
<input name={'title'} />
</div>
decorator 的巧妙用法
decorator + component 的组合,可以将两个组件放在一个 schema 节点里,降低 schema 结构复杂度,提高组件的复用率。
例如表单场景里,可以将 FormItem 组件与任意字段组件组合,在这里 FormItem 就是 Decorator。
{
type: 'void',
['x-component']: 'div',
properties: {
title: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
content: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input.TextArea',
},
},
}
JSX 等同于
<div>
<FormItem>
<Input name={'title'} />
</FormItem>
<FormItem>
<Input.TextArea name={'content'} />
</FormItem>
</div>
也可以提供一个 CardItem 组件,用于包裹所有区块,这样所有区块就都是 Card 包裹的了。
{
type: 'void',
['x-component']: 'div',
properties: {
title: {
type: 'string',
'x-decorator': 'CardItem',
'x-component': 'Table',
},
content: {
type: 'string',
'x-decorator': 'CardItem',
'x-component': 'Kanban',
},
},
}
JSX 等同于
<div>
<CardItem>
<Table />
</CardItem>
<CardItem>
<Kanban />
</CardItem>
</div>
组件的展示状态
'x-display': 'visible'
:显示组件'x-display': 'hidden'
:隐藏组件,数据不隐藏'x-display': 'none'
:隐藏组件,数据也隐藏
'x-display': 'visible'
{
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
'x-component': 'input',
'x-display': 'visible'
},
},
}
JSX 等同于
<div className={'form-item'}>
<input name={'title'} />
</div>
'x-display': 'hidden'
{
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
'x-component': 'input',
'x-display': 'hidden'
},
},
}
JSX 等同于
<div className={'form-item'}>
{/* 此处不输出 input 组件,对应的 name=title 的字段模型还存在 */}
</div>
'x-display': 'none'
{
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
'x-component': 'input',
'x-display': 'none'
},
},
}
JSX 等同于
<div className={'form-item'}>
{/* 此处不输出 input 组件,对应的 name=title 的字段模型也不存在了 */}
</div>
组件的显示模式
用于字段组件,有三种显示模式:
'x-pattern': 'editable'
可编辑'x-pattern': 'disabled'
不可编辑'x-pattern': 'readPretty'
友好阅读
如单行文本 <SingleText />
组件,编辑和不可编辑模式为 <input />
,友好阅读模式为 <div />
'x-pattern': 'editable'
const schema = {
name: 'test',
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
default: 'Hello',
'x-component': 'SingleText',
'x-pattern': 'editable'
},
},
};
JSX 等同于
<div className={'form-item'}>
<input name={'title'} value={'Hello'} />
</div>
'x-pattern': 'disabled'
const schema = {
name: 'test',
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
default: 'Hello',
'x-component': 'SingleText',
'x-pattern': 'disabled'
},
},
};
JSX 等同于
<div className={'form-item'}>
<input name={'title'} value={'Hello'} disabled />
</div>
'x-pattern': 'readPretty'
const schema = {
name: 'test',
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
default: 'Hello',
'x-component': 'SingleText',
'x-pattern': 'readPretty',
},
},
};
JSX 等同于
<div className={'form-item'}>
<div>Hello</div>
</div>