formily自定义组件步骤
- connect 桥接组件,antd 组件和 formily的桥接
- 定义桥接组件的 Resource� 配置,例如 Tree.Resource
- template:组件模板
- 物料的 json schema
- 定义桥接组件的 Behavior� 属性描述,例如 Tree.Behavior
https://github.com/alibaba/designable/discussions/136
https://zhuanlan.zhihu.com/p/431263711
https://www.yuque.com/aspirantzhang/antdprov5/iwibfb
Formily框架中,调用组件时,会自动注入几个属性
- value
- onChange对 Form实例对象上的对应 name表单项的 value进行修改
- dataSource,比如在Select中,就是通过JSON描述的Enum值
- onBlur,JSON中的default字段改
- onFocus
渲染时
场景:用于渲染成 jsx时,只用于 JsonSchema解析时
x-component 对应的组件字符串
编辑时
编辑器交互显示
- Resource:配置组件库的小部件 weigets展示
- 职责就是用于代码的生成。在生成代码阶段
- 设计器中所有涉及到节点修改的地方,其实都是针对 TreeNode 这个虚拟节点树对象进行操作
- 在 designable 底层它会被转换为 Formily Schema
- Behavior:配置预览组件在 Canvas 中的操作配置
- 比如是否可拖拽、可删除、可复制等功能
- 用于定义组件的所有可交互的接口,例如控制与限制拖拽生成阶段的容器与层级关系,比如限定某个组件只能拖拽到固定的视图节点
weigets
disignable组件四种展形态
1. 小部件 widget
2. 预览态 Preview
3. 渲染态 RenderComponent
4. 只读态 Readonly
Behavior
以 Rate组件为例拆分组件
从 components目录下,找一个简单的组件为例,来了解 designable组件的组成
import React from 'react'
import { Rate as AntdRate } from 'antd'
import { createBehavior, createResource } from '@designable/core'
import { DnFC } from '@designable/react'
import { createFieldSchema } from '../Field'
import { AllSchemas } from '../../schemas'
import { AllLocales } from '../../locales'
export const Rate: DnFC<React.ComponentProps<typeof AntdRate>> = AntdRate
Rate.Behavior = createBehavior({
name: 'Rate',
extends: ['Field'],
// @ts-ignore
selector: (node) => node.props['x-component'] === 'Rate',
designerProps: {
propsSchema: createFieldSchema(AllSchemas.Rate),
},
designerLocales: AllLocales.Rate,
})
Rate.Resource = createResource({
// 展示的图标
icon: 'RateSource',
// 预定义的模板,就是拖拽到画布上显示的属性
elements: [
{
componentName: 'Field',
props: {
type: 'number',
title: 'Rate',
'x-decorator': 'FormItem',
'x-component': 'Rate',
},
},
],
})
icon
createResource下的 icon来源designable/packages/react/src/icons
- 支持 svg标签
- 支持 *.png文件 路径引入的
图片 icon样式icon: 'RateSource'
icon: <svg></svg>
icon: 'https://img.alicdn.com/imgextra/i1/O1CN01jnfLpK1rFJ4nPj9Pt_!!6000000005601-55-tps-56-56.svg'
.dn-resource-item-icon {
width: 56px;
height: 40px;
display: flex;
justify-content: center;
align-items: center;
}
自定义 icon
designzble 自定义 icon参考 designable/packages/react/src/containers/Designer.tsx
import { Engine, GlobalRegistry } from '@designable/core'
import * as icons from '../icons'
GlobalRegistry.registerDesignerIcons(icons)
Select 远程数据
Select组件增加一个远程数据源,实现思路
- 自己封装一个带请求的 Select
- 选择 Select组件,选择
- 响应器规则 - 配置响应器
- 选择动作响应,右侧一个 Async Select
- 直接在这里写请求逻辑
formily自定义 Tree组件
桥接 formily
https://www.yuque.com/xjchenhao/development/dhv90n
https://blog.csdn.net/tianxintiandisheng/article/details/124858824
自定义组件的 Resource & Behavior
import React from 'react'
import { Tree as AntdTree } from 'antd'
import { TreeProps } from 'antd/lib/tree'
import { connect, mapReadPretty, mapProps, ReactFC } from '@formily/react'
import { PreviewText } from '@formily/antd/lib/preview-text'
import { createBehavior, createResource } from '@designable/core'
import { DnFC } from '@designable/react'
import { LoadingOutlined } from '@ant-design/icons'
import { createFieldSchema } from '../Field'
import { AllSchemas } from '../../schemas'
import { AllLocales } from '../../locales'
// 1 桥接组件
export const AntTree: ReactFC<TreeProps<any, any>> = connect(
AntdTree,
mapProps(
{
dataSource: 'treeData',
loading: true,
},
(props: any, field) => {
return {
...props,
suffixIcon:
field?.['loading'] || field?.['validating'] ? (
<LoadingOutlined />
) : (
props.suffixIcon
),
}
}
),
mapReadPretty(PreviewText.Tree)
)
export const Tree: DnFC<React.ComponentProps<typeof AntdTree>> = AntTree
// 行为
// @ts-ignore
Tree.Behavior = createBehavior({
name: 'Tree',
extends: ['Field'],
selector: (node) => {
// @ts-ignore
return node.props['x-component'] === 'Tree'
},
designerProps: {
// 组件默认属性配置
propsSchema: createFieldSchema(AllSchemas.Tree),
},
designerLocales: AllLocales.Tree,
})
// 资源
// @ts-ignore
Tree.Resource = createResource({
icon: 'https://alifd.alicdn.com/fusion-cool/icons/icon-antd/tree-1.jpg',
elements: [
{
componentName: 'Field',
props: {
type: 'string',
title: 'Tree',
// 'x-decorator': 'FormItem',
'x-component': 'Tree',
},
},
],
title: 'Tree组件',
// description?: string | IDesignerMiniLocales
// thumb?: string
// span?: number
// elements?: ITreeNode[]
})