跳到主要内容

设置器自定义

属性设置器用于在配置面板中展示特定配置项的配置逻辑。Tango 内置了多种标准的属性设置器,对于一些特殊场景,内置的属性设置器可能无法满足你的需要,此时开发者可以扩展自己的属性设置。

设置器类型

Tango 的属性设置器分为两种类型:

  • 值设置器(value setter): 设置器接收和返回的是一个具体的 javascript value 值,例如字符串、数字、布尔值、对象等。值设置器支持与代码设置器进行相互切换。
  • 代码设置器(code setter): 设置器接收和返回的是一个 javascript 代码片段。

与之相对应的,在引擎的内核层,在解析属性值时,有两种策略:

  1. 基本类型会被直接解析为值,例如字符串、数字、布尔值等。
  2. 复杂类型会被解析为代码,例如函数、非标准对象、非标准数组等。

属性值的解析和设置流程如下图所示: setter type

引擎如何区分字符串和代码片段

为了能够正确区分普通的字符串值和代码片段,Tango 引擎在解析过程中进行了区分。代码片段始终使用 "{{code}}" 进行包裹,例如 "{{() => {}}}"

引擎是如何解析对象的

对于简单的对象,例如 { key: 'value' },引擎会将其解析为值。而对于复杂的对象,例如函数、带计算的对象或数组、带引用的对象或数组,都会统一将其解析为代码片段。

内置的设置器

Value setter

对于值设置器而言,直接接收和返回具体的 javascript value 即可。

设置器名接收值类型说明和示例
numberSetternumber数字值设置器
textSetterstring文本值设置器
boolSetterbooleantruefalse
choiceSetterstring单选列表,多选一
selectSetterstring下拉选择器,多选一
actionListSetterobject[][{ key, label, ...}, ...]
columnSetterobject[]表格列设置器 [{ key, dataIndex, title, ... }, ...]
dateSetterstring日期值设置器
dateRangeSetterstring[]日期范围设置器
timeSetterstring时间值设置器
timeRangeSetterstring[]时间范围设置器
enumSetterobject枚举对象 { key1, key2, key3 }
listSetterobject[]通用的对象列表设置器, [{ key }, ...]
optionSetterobject[]选项列表设置器, [{ label, value }, ...]
routerSetterstring路由设置器

Code setter

对于代码设置器而言,直接接收和返回代码字符串即可。

设置器名接收值类型说明和示例
codeSettercode通用的代码片段设置器
eventSettercode事件监听函数设置器, () => {}
jsonSettercodeJSON 表达式设置器, { "foo": "foo" }
jsxSettercodeJSX 设置器, <div>block</div>
renderPropsSettercoderender props 设置器, () => <div></div>
tableCellSettercode表格单元格设置器
tableExpandableSettercode表格展开设置器
引擎是何时对返回值进行包裹的

代码设置器之需要直接返回代码片段即可,外层的表单状态容器会自动进行返回值的处理。例如 codeSetter 直接返回 "{ foo: "foo" }" 代码片段,在经过 FormModel 的处理后,会将其包裹为 "{{{ foo: "foo" }}},并传递给引擎内核进行后续的处理。

注册自定义属性设置器

属性设置器的实现标准

属性设置器组件是一个标准的受控型表单组件,开发者所开发的组件只需要暴露 valueonChange(value) 两个属性让属性面板的表单容器进行控制即可。例如,我们可以实现一个简单的字符串设置器 StringSetter,其实现如下:

function StringSetter({ value, onChange, ...rest }) {
const handleChange = (e) => {
onChange(e.target.value);
};
return <input value={value} onChange={handleChange} />;
}

属性的清空

如果需要清空一个属性(在设计器中会移除掉该属性),只需要在 setter 的 onChange 中返回 undefined 即可。例如,在下面的例子中,我们在 StringSetter 中添加了一个清空按钮,点击该按钮会清空当前的属性值。

function StringSetter({ value, onChange, ...rest }) {
const handleChange = (e) => {
onChange(e.target.value);
};
return (
<div>
<input value={value} onChange={handleChange} />
<button onClick={() => onChange(undefined)}>X</button>
</div>
);
}

注册属性设置器

注册属性设置器非常简单,只需要借助设置器暴露出来的 registerSetter 即可。

import { registerSetter } from '@music163/tango-designer';

// 注册自定义 setter
registerSetter({
name: 'stringSetter',
component: StringSetter,
});

registerSetter 接收的配置如下:

属性说明类型默认值
name设置器名称string-
alias设置器别名string[]-
component设置器组件ReactComponent-
type设置器类型'value' | 'code''value'
validate设置器校验(value) => errorMsg-

使用自定义的属性设置器

在组件的物料协议中直接声明对应的属性设置器名称即可。例如:

const prototype = {
name: 'PageHeader',
title: 'PageHeader',
props: [
{
name: 'title',
title: '标题',
setter: 'stringSetter',
},
],
};

属性设置器组件 SettingPanel

设置器组件一个属性配置表单,用于展示组件的属性配置项。

属性说明类型默认值
title面板标题string-
defaultValue默认值object-
groupOptions分组选项object-
model表单状态管理实例FormModel-
onChange值变化回调(name, value, field) => void-
prototype组件的可配置描述ComponentPrototype-
renderItemExtra自定义渲染表单项的额外内容(标签右侧)(props) => ReactNode-
showGroups是否展示分组boolean-
showItemSubtitle是否展示表单项的副标题boolean-
showSearch是否展示搜索框boolean-