nocobase/docs/zh-CN/development/guide/ui-schema-designer/what-is-ui-schema.md
Junyi 796e73ae5a
refactor(doc): change to new structure (#804)
* refactor(doc): change to new structure

* docs: add database docs

* docs: add collection docs

* docs: add db field examples

* docs(api): fix filename and menu path

* docs: add database docs

* docs: add db operators doc

* docs: add resourcer menu

* docs: add resourcer docs

* docs: fix api docs

* docs: refactor api menu structure

* feat: update docs (#830)

* feat: updates

* feat: update docs

* chore: ignore docs from ci

Co-authored-by: Junyi <mytharcher@users.noreply.github.com>
Co-authored-by: mytharcher <mytharcher@gmail.com>

* docs: add database methods docs

* docs: add missed api

* docs: fix api docs

* feat: update development docs (#833)

* feat: update development docs

* feat: update docs

* feat: update docs

* docs: add first plugin example (#834)

* feat: update docs

* feat: update docs

* docs: fix typo

Co-authored-by: chenos <chenlinxh@gmail.com>
2022-09-19 09:23:01 +08:00

5.8 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;
  // 组件的子节点,简单使用
  ['x-content']?: any;
  // 展示状态,默认为 'visible'
  ['x-display']?: 'none' | 'hidden' | 'visible';
  // children 节点 schema
  properties?: Record<string, ISchema>;

  // 以下仅字段组件时使用

  // 字段联动
  ['x-reactions']?: SchemaReactions;
  // 字段 UI 交互模式,默认为 'editable'
  ['x-pattern']?: 'editable' | 'disabled' | 'readOnly' | 'readPretty';
  // 字段校验
  ['x-validator']?: FieldValidator;
  // 默认数据
  default: ?:any;

  // 设计器相关

  // 设计器组件(工具栏)
  ['x-designer']?: any;
  // 初始化器组件(工具栏)
  ['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>