增加自定义组件

想要拓展一个 designable 工程的自定义组件,需要拓展两个不同的组件。分别是:

  1. “编辑态”组件。在编辑阶段时使用,它可能包含一些操作按钮,参看官方 demo 里的“自增表格”组件
  2. “渲染态”组件。在渲染阶段时使用,它是单纯的渲染组件,是真正交付到客户端使用的组件。它可以单纯的当作 antd 的ProComponents使用。

“编辑态”组件开发

自定义组件包含三个部分,分别是:

  • template:组件模板
  • Behavior:组件行为的描述
  • Resource:组件资源的描述

一码胜千言

  1. import { createBehavior, createResource } from '@designable/core';
  2. import { createFieldSchema } from '@designable/formily-antd';
  3. import { DnFC } from '@designable/react';
  4. // 组件模版,这部分可以写的很复杂
  5. export const CustomComponent: DnFC = ({ ...props }) => {
  6. // props对应Resource的x-component-props
  7. return (
  8. <div>
  9. {/* 也可以以高级组件的形式使用:{props.children}*/}
  10. <input type="text" {...props} />
  11. </div>
  12. );
  13. };
  14. // 组件行为的描述
  15. CustomComponent.Behavior = createBehavior({
  16. name: 'CustomComponent',
  17. extends: ['Field'], // 好像只能填Field
  18. selector: (node) => node.props['x-component'] === 'CustomComponent', // 与Resource的x-component的值匹配上才生效
  19. designerProps: {
  20. // createFieldSchema的值如果是空对象,则“属性配置”面板中没有“组件属性”。
  21. // 如果把createFieldSchema换成createVoidFieldSchema函数,字段属性一栏将只保留必要的配置项。
  22. propsSchema: createFieldSchema({
  23. type: 'object',
  24. properties: {
  25. customFieldName: {
  26. type: 'number',
  27. title: '字段属性',
  28. 'x-decorator': 'FormItem',
  29. 'x-component': 'NumberPicker',
  30. 'x-component-props': {
  31. defaultValue: 100,
  32. },
  33. },
  34. },
  35. }),
  36. },
  37. // 语言翻译
  38. designerLocales: {
  39. 'zh-CN': {
  40. title: '我的输入框',
  41. settings: {
  42. 'x-component-props': {
  43. customFieldName: '自定义字段名称',
  44. },
  45. },
  46. },
  47. 'en-US': {
  48. title: 'Input',
  49. settings: {
  50. 'x-component-props': {
  51. customFieldName: 'customFieldName',
  52. },
  53. },
  54. },
  55. },
  56. });
  57. // 组件资源的描述
  58. CustomComponent.Resource = createResource({
  59. icon: 'InputSource', // 体现在组件栏的icon
  60. elements: [
  61. {
  62. componentName: 'Field', // 好像只能填Field
  63. // 下面的传参 就是formily的Field的属性配置。具体见此链接的文末:https://www.formilyjs.org/zh-CN/guide/quick-start#%E5%85%B7%E4%BD%93%E7%94%A8%E4%BE%8B
  64. props: {
  65. type: 'String', // 返回的数据类型,
  66. title: '你好呀', // 对应“属性设置”里的标题字段
  67. 'x-decorator': 'FormItem', // 目前只有`FormItem`值会改变组件形态为“表单字段”,填其它值跟没写没有两样。如果不希望组件以表单字段的形式呈现,不写x-decorator和title字段即可。
  68. 'x-component': 'CustomComponent', // 对应的组件
  69. // 组件“属性设置”的默认值,也会体现在组件的props中。
  70. 'x-component-props': {
  71. placeholder: '占位占位',
  72. maxLength: 3,
  73. },
  74. },
  75. },
  76. ],
  77. });

模块结构

上述代码把组件、组件属性、组件语言翻译耦合在一个文件中,最好做如下解耦。

官方示例看这里

  1. .
  2. ├── components
  3. ├── CustomComponent
  4. ├── index.ts
  5. └── preview.tsx
  6. └── index.ts
  7. ├── index.ts
  8. ├── locales
  9. ├── Input.ts
  10. ├── all.ts
  11. └── index.ts
  12. └── schemas
  13. ├── Input.ts
  14. ├── all.ts
  15. └── index.ts

“渲染态”组件开发

渲染态的组件开发相对比较简单,参看官方示例很容易就能写出来。

一码胜千言

  1. import React from 'react';
  2. export const QueryList: React.FC = ({ ...props }) => {
  3. console.log(props); // 以此接收配置的参数。
  4. return (
  5. <div {...props}>
  6. <p>我是自定组件</p>
  7. </div>
  8. );
  9. };