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>> = AntdRateRate.Behavior = createBehavior({name: 'Rate',extends: ['Field'],// @ts-ignoreselector: (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-ignoreTree.Behavior = createBehavior({name: 'Tree',extends: ['Field'],selector: (node) => {// @ts-ignorereturn node.props['x-component'] === 'Tree'},designerProps: {// 组件默认属性配置propsSchema: createFieldSchema(AllSchemas.Tree),},designerLocales: AllLocales.Tree,})// 资源// @ts-ignoreTree.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[]})
