自定义 formily表单组件核心步骤

  1. 实现 Formily桥接 UI组件
  2. 实现 Behavior属性配置,createBehavior�
    1. 组件属性配置,createFieldSchema�
  3. 实现 Resource资源配置,createResource�

formily 组件业务模型

  1. 定义组件
  2. 引入 schemas 模型
  3. 引入 locales多语言,针对国内用户,可以忽略 ```tsx import type React from ‘react’ import { Submit as FormilySubmit } from ‘@formily/antd’ import { createBehavior, createResource } from ‘@designable/core’ import type { DnFC } from ‘@designable/react’ import { createFieldSchema } from ‘../Field’ import { AllSchemas } from ‘../../schemas’ import { AllLocales } from ‘../../locales’

export const Submit: DnFC> = FormilySubmit

  1. 桥接的自定义表单组件位置,components/<br />先找个组件复制一下,然后重命名组件,不要和已有的组件重名
  2. - Submit.Behavior
  3. - Submit.Resource
  4. ![image.png](https://cdn.nlark.com/yuque/0/2023/png/112859/1672843505168-03c232d3-5957-43fb-abfb-35065ca754a3.png#averageHue=%232d2c2b&clientId=ud63acbf0-01c6-4&from=paste&height=284&id=QDCvC&originHeight=928&originWidth=1736&originalType=binary&ratio=1&rotation=0&showTitle=false&size=159491&status=done&style=none&taskId=uc844b931-d556-473c-814a-5e83275a399&title=&width=530.9985656738281)
  5. <a name="bGhIa"></a>
  6. ### createDesigner 注册组件
  7. 左侧�面板,`<CompositePanel>` 注册自定义的组件�
  8. ```tsx
  9. import { Submit } from './components'
  10. // sources注册组件
  11. <ResourceWidget
  12. title="sources.Displays"
  13. sources={[Text, Tree, Submit]}
  14. />
  15. function App() {
  16. return (
  17. <Designer engine={engine}>
  18. <StudioPanel
  19. logo={<LogoWidget/>}
  20. actions={<ActionsWidget/>}
  21. >
  22. <CompositePanel>
  23. <CompositePanel.Item
  24. title="原子组件" // panels.Component
  25. icon="Component"
  26. >
  27. <ResourceWidget
  28. title="sources.Displays" // 展示组件
  29. sources={[Text, Tree, Submit]}
  30. />
  31. </CompositePanel.Item>
  32. </CompositePanel>
  33. </Designer>
  34. )
  35. }

Behavior�

  1. Submit.Behavior = createBehavior({
  2. name: 'Submit',
  3. extends: ['Field'],
  4. selector: (node: any) => node.props['x-component'] === 'Submit',
  5. designerProps: {
  6. propsSchema: createFieldSchema(AllSchemas.Submit),
  7. },
  8. designerLocales: AllLocales.Submit,
  9. })

createBehavior�

  1. Submit.Behavior = createBehavior({
  2. name: '组件名字',
  3. extends: ['Field'],
  4. selector: (node: any) => node.props['x-component'] === 'Submit',
  5. designerProps: {
  6. propsSchema: {}
  7. },
  8. designerLocales: {}
  9. });

propsSchema 组件属性

就是右侧,属性配置,可以展示的字段

designerLocales 多语言

就是对 API 字段的说明

  1. export const Submit = {
  2. 'zh-CN': {
  3. title: '提交',
  4. settings: {
  5. 'x-component-props': {
  6. type: {
  7. title: '按钮类型',
  8. dataSource: [
  9. 'primary',
  10. 'link',
  11. 'text',
  12. 'ghost',
  13. 'dashed',
  14. 'default',
  15. ],
  16. },
  17. autoClearSearchValue: {
  18. title: '选中自动清除',
  19. tooltip: '仅在多选或者标签模式下支持',
  20. },
  21. defaultActiveFirstOption: '默认高亮第一个选项',
  22. dropdownMatchSelectWidth: {
  23. title: '下拉菜单和选择器同宽',
  24. tooltip:
  25. '默认将设置 min-width,当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动',
  26. },
  27. defaultOpen: '默认展开',
  28. filterOption: '选项筛选器',
  29. filterSort: '选项排序器',
  30. labelInValue: {
  31. title: '标签值',
  32. tooltip:
  33. '是否把每个选项的 label 包装到 value 中,会把 Select 的 value 类型从 string 变为 { value: string, label: ReactNode } 的格式',
  34. },
  35. listHeight: '弹窗滚动高度',
  36. maxTagCount: {
  37. title: '最多标签数量',
  38. tooltip: '最多显示多少个 tag,响应式模式会对性能产生损耗',
  39. },
  40. maxTagPlaceholder: {
  41. title: '最多标签占位',
  42. tooltip: '隐藏 tag 时显示的内容',
  43. },
  44. maxTagTextLength: '最多标签文本长度',
  45. showArrow: '显示箭头',
  46. virtual: '开启虚拟滚动',
  47. },
  48. },
  49. },
  50. 'en-US': {
  51. title: 'Submit',
  52. settings: {
  53. 'x-component-props': {
  54. mode: {
  55. title: 'Mode',
  56. dataSource: ['Multiple', 'Tags', 'Single'],
  57. },
  58. autoClearSearchValue: {
  59. title: 'Auto Clear Search Value',
  60. tooltip: 'Only used to multiple and tags mode',
  61. },
  62. defaultActiveFirstOption: 'Default Active First Option',
  63. dropdownMatchSelectWidth: 'Dropdown Match Select Width',
  64. defaultOpen: 'Default Open',
  65. filterOption: 'Filter Option',
  66. filterSort: 'Filter Sort',
  67. labelInValue: 'label InValue',
  68. listHeight: 'List Height',
  69. maxTagCount: 'Max Tag Count',
  70. maxTagPlaceholder: {
  71. title: 'Max Tag Placeholder',
  72. tooltip: 'Content displayed when tag is hidden',
  73. },
  74. maxTagTextLength: 'Max Tag Text Length',
  75. showArrow: 'Show Arrow',
  76. virtual: 'Use Virtual Scroll',
  77. },
  78. },
  79. }
  80. }

Resource�

icon图标

  • 字符串,已注册的 svg名字
  • svg标签
  1. Submit.Resource = createResource({
  2. icon: 'SubmitSource',
  3. elements: [
  4. {
  5. componentName: 'Field',
  6. props: {
  7. title: 'Submit',
  8. 'x-decorator': 'FormItem',
  9. 'x-component': 'Submit',
  10. },
  11. },
  12. ],
  13. })

icon 图标

icon 图标组件路径,designable/packages/react/src/icons
image.png

createFieldSchema� 组件属性

组件属性配置,就是 antd组件的 API支持的属性

  • type: ‘object’
  • properties: {}

image.png

  1. import type { ISchema } from '@formily/react'
  2. export const Submit: ISchema = {
  3. type: 'object',
  4. properties: {
  5. mode: {
  6. type: 'string',
  7. enum: ['multiple', 'tags', null],
  8. 'x-decorator': 'FormItem',
  9. 'x-component': 'Radio.Group',
  10. 'x-component-props': {
  11. defaultValue: null,
  12. optionType: 'button',
  13. },
  14. },
  15. allowClear: {
  16. type: 'boolean',
  17. 'x-decorator': 'FormItem',
  18. 'x-component': 'Switch',
  19. },
  20. autoClearSearchValue: {
  21. type: 'boolean',
  22. 'x-decorator': 'FormItem',
  23. 'x-component': 'Switch',
  24. 'x-component-props': {
  25. defaultChecked: true,
  26. },
  27. },
  28. dropdownMatchSelectWidth: {
  29. type: 'boolean',
  30. 'x-decorator': 'FormItem',
  31. 'x-component': 'Switch',
  32. 'x-component-props': {
  33. defaultChecked: true,
  34. },
  35. },
  36. autoFocus: {
  37. type: 'boolean',
  38. 'x-decorator': 'FormItem',
  39. 'x-component': 'Switch',
  40. },
  41. bordered: {
  42. type: 'boolean',
  43. 'x-decorator': 'FormItem',
  44. 'x-component': 'Switch',
  45. 'x-component-props': {
  46. defaultChecked: true,
  47. },
  48. },
  49. defaultActiveFirstOption: {
  50. type: 'boolean',
  51. 'x-decorator': 'FormItem',
  52. 'x-component': 'Switch',
  53. 'x-component-props': {
  54. defaultChecked: true,
  55. },
  56. },
  57. defaultOpen: {
  58. type: 'boolean',
  59. 'x-decorator': 'FormItem',
  60. 'x-component': 'Switch',
  61. },
  62. labelInValue: {
  63. type: 'boolean',
  64. 'x-decorator': 'FormItem',
  65. 'x-component': 'Switch',
  66. },
  67. showArrow: {
  68. type: 'boolean',
  69. 'x-decorator': 'FormItem',
  70. 'x-component': 'Switch',
  71. },
  72. showSearch: {
  73. type: 'boolean',
  74. 'x-decorator': 'FormItem',
  75. 'x-component': 'Switch',
  76. },
  77. virtual: {
  78. type: 'boolean',
  79. 'x-decorator': 'FormItem',
  80. 'x-component': 'Switch',
  81. 'x-component-props': {
  82. defaultValue: true,
  83. },
  84. },
  85. filterOption: {
  86. type: 'boolean',
  87. 'x-decorator': 'FormItem',
  88. 'x-component': 'ValueInput',
  89. 'x-component-props': {
  90. include: ['BOOLEAN', 'EXPRESSION'],
  91. },
  92. },
  93. filterSort: {
  94. type: 'boolean',
  95. 'x-decorator': 'FormItem',
  96. 'x-component': 'ValueInput',
  97. 'x-component-props': {
  98. include: ['EXPRESSION'],
  99. },
  100. },
  101. listHeight: {
  102. type: 'number',
  103. 'x-decorator': 'FormItem',
  104. 'x-component': 'NumberPicker',
  105. 'x-component-props': {
  106. defaultValue: 256,
  107. },
  108. },
  109. maxTagCount: {
  110. type: 'number',
  111. 'x-decorator': 'FormItem',
  112. 'x-component': 'NumberPicker',
  113. },
  114. maxTagPlaceholder: {
  115. type: 'string',
  116. 'x-decorator': 'FormItem',
  117. 'x-component': 'Input',
  118. },
  119. maxTagTextLength: {
  120. type: 'number',
  121. 'x-decorator': 'FormItem',
  122. 'x-component': 'NumberPicker',
  123. },
  124. notFoundContent: {
  125. type: 'string',
  126. 'x-decorator': 'FormItem',
  127. 'x-component': 'Input',
  128. 'x-component-props': {
  129. defaultValue: 'Not Found',
  130. },
  131. },
  132. placeholder: {
  133. type: 'string',
  134. 'x-decorator': 'FormItem',
  135. 'x-component': 'Input',
  136. },
  137. size: {
  138. type: 'string',
  139. enum: ['large', 'small', 'middle', null],
  140. 'x-decorator': 'FormItem',
  141. 'x-component': 'Select',
  142. 'x-component-props': {
  143. defaultValue: 'middle',
  144. },
  145. },
  146. },
  147. }

schemas� 组件模型

locales� 多语言