自定义 formily表单组件核心步骤
- 实现 Formily桥接 UI组件
- 实现 Behavior属性配置,createBehavior�
- 组件属性配置,createFieldSchema�
- 实现 Resource资源配置,createResource�
formily 组件业务模型
- 定义组件
- 引入 schemas 模型
- 引入 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
桥接的自定义表单组件位置,components/<br />先找个组件复制一下,然后重命名组件,不要和已有的组件重名
- Submit.Behavior
- Submit.Resource
![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)
<a name="bGhIa"></a>
### createDesigner 注册组件
左侧�面板,`<CompositePanel>` 注册自定义的组件�
```tsx
import { Submit } from './components'
// sources注册组件
<ResourceWidget
title="sources.Displays"
sources={[Text, Tree, Submit]}
/>
function App() {
return (
<Designer engine={engine}>
<StudioPanel
logo={<LogoWidget/>}
actions={<ActionsWidget/>}
>
<CompositePanel>
<CompositePanel.Item
title="原子组件" // panels.Component
icon="Component"
>
<ResourceWidget
title="sources.Displays" // 展示组件
sources={[Text, Tree, Submit]}
/>
</CompositePanel.Item>
</CompositePanel>
</Designer>
)
}
Behavior�
Submit.Behavior = createBehavior({
name: 'Submit',
extends: ['Field'],
selector: (node: any) => node.props['x-component'] === 'Submit',
designerProps: {
propsSchema: createFieldSchema(AllSchemas.Submit),
},
designerLocales: AllLocales.Submit,
})
createBehavior�
Submit.Behavior = createBehavior({
name: '组件名字',
extends: ['Field'],
selector: (node: any) => node.props['x-component'] === 'Submit',
designerProps: {
propsSchema: {}
},
designerLocales: {}
});
propsSchema 组件属性
就是右侧,属性配置,可以展示的字段
designerLocales 多语言
就是对 API 字段的说明
export const Submit = {
'zh-CN': {
title: '提交',
settings: {
'x-component-props': {
type: {
title: '按钮类型',
dataSource: [
'primary',
'link',
'text',
'ghost',
'dashed',
'default',
],
},
autoClearSearchValue: {
title: '选中自动清除',
tooltip: '仅在多选或者标签模式下支持',
},
defaultActiveFirstOption: '默认高亮第一个选项',
dropdownMatchSelectWidth: {
title: '下拉菜单和选择器同宽',
tooltip:
'默认将设置 min-width,当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动',
},
defaultOpen: '默认展开',
filterOption: '选项筛选器',
filterSort: '选项排序器',
labelInValue: {
title: '标签值',
tooltip:
'是否把每个选项的 label 包装到 value 中,会把 Select 的 value 类型从 string 变为 { value: string, label: ReactNode } 的格式',
},
listHeight: '弹窗滚动高度',
maxTagCount: {
title: '最多标签数量',
tooltip: '最多显示多少个 tag,响应式模式会对性能产生损耗',
},
maxTagPlaceholder: {
title: '最多标签占位',
tooltip: '隐藏 tag 时显示的内容',
},
maxTagTextLength: '最多标签文本长度',
showArrow: '显示箭头',
virtual: '开启虚拟滚动',
},
},
},
'en-US': {
title: 'Submit',
settings: {
'x-component-props': {
mode: {
title: 'Mode',
dataSource: ['Multiple', 'Tags', 'Single'],
},
autoClearSearchValue: {
title: 'Auto Clear Search Value',
tooltip: 'Only used to multiple and tags mode',
},
defaultActiveFirstOption: 'Default Active First Option',
dropdownMatchSelectWidth: 'Dropdown Match Select Width',
defaultOpen: 'Default Open',
filterOption: 'Filter Option',
filterSort: 'Filter Sort',
labelInValue: 'label InValue',
listHeight: 'List Height',
maxTagCount: 'Max Tag Count',
maxTagPlaceholder: {
title: 'Max Tag Placeholder',
tooltip: 'Content displayed when tag is hidden',
},
maxTagTextLength: 'Max Tag Text Length',
showArrow: 'Show Arrow',
virtual: 'Use Virtual Scroll',
},
},
}
}
Resource�
icon图标
- 字符串,已注册的 svg名字
- svg标签
Submit.Resource = createResource({
icon: 'SubmitSource',
elements: [
{
componentName: 'Field',
props: {
title: 'Submit',
'x-decorator': 'FormItem',
'x-component': 'Submit',
},
},
],
})
icon 图标
icon 图标组件路径,designable/packages/react/src/icons
createFieldSchema� 组件属性
组件属性配置,就是 antd组件的 API支持的属性
- type: ‘object’
- properties: {}
import type { ISchema } from '@formily/react'
export const Submit: ISchema = {
type: 'object',
properties: {
mode: {
type: 'string',
enum: ['multiple', 'tags', null],
'x-decorator': 'FormItem',
'x-component': 'Radio.Group',
'x-component-props': {
defaultValue: null,
optionType: 'button',
},
},
allowClear: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
},
autoClearSearchValue: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
'x-component-props': {
defaultChecked: true,
},
},
dropdownMatchSelectWidth: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
'x-component-props': {
defaultChecked: true,
},
},
autoFocus: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
},
bordered: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
'x-component-props': {
defaultChecked: true,
},
},
defaultActiveFirstOption: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
'x-component-props': {
defaultChecked: true,
},
},
defaultOpen: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
},
labelInValue: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
},
showArrow: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
},
showSearch: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
},
virtual: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'Switch',
'x-component-props': {
defaultValue: true,
},
},
filterOption: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'ValueInput',
'x-component-props': {
include: ['BOOLEAN', 'EXPRESSION'],
},
},
filterSort: {
type: 'boolean',
'x-decorator': 'FormItem',
'x-component': 'ValueInput',
'x-component-props': {
include: ['EXPRESSION'],
},
},
listHeight: {
type: 'number',
'x-decorator': 'FormItem',
'x-component': 'NumberPicker',
'x-component-props': {
defaultValue: 256,
},
},
maxTagCount: {
type: 'number',
'x-decorator': 'FormItem',
'x-component': 'NumberPicker',
},
maxTagPlaceholder: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
maxTagTextLength: {
type: 'number',
'x-decorator': 'FormItem',
'x-component': 'NumberPicker',
},
notFoundContent: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
'x-component-props': {
defaultValue: 'Not Found',
},
},
placeholder: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
size: {
type: 'string',
enum: ['large', 'small', 'middle', null],
'x-decorator': 'FormItem',
'x-component': 'Select',
'x-component-props': {
defaultValue: 'middle',
},
},
},
}