Skip to content

Combine ​

概述 ​

Combine组合字段组件,将多个子字段组件组合起来共同输入一个状态值。各子字段独立交互,值经toState聚合为一个状态值写入 store;状态值变化时又经各子字段的toInput拆分回填,适合内边距、坐标、尺寸这类由多个部分构成的单值场景。

示例 ​

声明一个组合字段需要指定widget: 'combine'并通过children提供子字段列表:

ts
const form = document.querySelector('#form');
form.state = {
    padding: configurable('10px 5px', {
        widget: 'combine',
        label: '内边距',
        children: [
            { name: 'top', label: '上', widget: 'range' },
            { name: 'right', label: '右', widget: 'range' },
        ],
    }),
};
loading

指南 ​

工作原理 ​

组合字段是纯粹的容器,数据的流动分为两个方向:

  • toState:任一子字段的值发生变化时触发,入参是各子字段当前值组成的数组,返回值聚合后的结果写入父字段的状态。
  • toInput:声明在各子字段上,入参是父字段的状态值,返回该子字段应显示的值。状态值变化时逐个子字段拆分回填。

以内边距为例,状态值是'10px 5px'这样的字符串,经parsePadding拆分为上/右/下/左四个数值分发给四个子字段;任一子字段变化后又经toPadding把数值数组拼回字符串:

ts
function parsePadding(padding: string) {
    const [top = 0, right = 0, bottom = 0, left = 0] = padding.trim().split(/\s+/).map((v) => parseInt(v, 10) || 0);
    return { top, right, bottom, left };
}
function toPadding(values: number[]) {
    return values.map((v) => `${v}px`).join(' ');
}

children 配置 ​

children是子字段的 schema 数组,每个子字段可以是任意 widget,并支持该 widget 自身的全部配置(min、choices、switchValues等),同时可声明name(作为列表 key)、label、width等布局属性:

ts
form.state = {
    padding: configurable('10px 5px', {
        widget: 'combine',
        label: '内边距',
        required: true,
        children: [
            {
                name: 'top',
                label: '上',
                widget: 'range',
                width: '50%',
                min: 0,
                max: 100,
            },
            {
                name: 'bottom',
                label: '下',
                widget: 'range',
                width: '50%',
                min: 0,
                max: 100,
            },
        ],
    }),
};

子项是「部分 schema」:不要求value(初值由父字段的toInput拆分而来)。

内边距四方向示例 ​

完整的四方向内边距编辑器,父字段提供toState聚合,四个子字段各自提供toInput拆分:

ts
form.state = {
    padding: configurable('10px 5px', {
        widget: 'combine',
        label: '内边距',
        toState: (values) => toPadding(values), 
        required: true,
        children: [
            {
                name: 'top',
                label: '上',
                widget: 'range',
                width: '50%',
                toInput: (value) => parsePadding(value).top, 
            },
            {
                name: 'right',
                label: '右',
                widget: 'range',
                width: '50%',
                toInput: (value) => parsePadding(value).right, 
            },
            {
                name: 'bottom',
                label: '下',
                widget: 'range',
                width: '50%',
                toInput: (value) => parsePadding(value).bottom, 
            },
            {
                name: 'left',
                label: '左',
                widget: 'range',
                width: '50%',
                toInput: (value) => parsePadding(value).left, 
            },
        ],
    }),
};
  • toState用于将子组件的值合并成一个值。
  • toInput用于将父组件的值拆分成子组件的值。

下拉开关 ​

dropdown控制子字段的呈现方式,默认true以弹层方式显示;false时子字段内联展示在表单中:

ts
form.state = {
    padding: configurable('10px 5px', {
        widget: 'combine',
        label: '内边距',
        dropdown: false, 
        children: [
            { name: 'top', label: '上', widget: 'range' },
            { name: 'right', label: '右', widget: 'range' },
        ],
    }),
};

属性 ​

属性 类型 默认值 说明
children array [] 必填。子字段 schema 数组,每个子字段可以是任意 widget
dropdown boolean true 是否以弹层方式展示子字段

注意事项 ​

  • children是必填配置,缺失时字段没有可交互内容。
  • 子字段的值不会写入独立的状态路径,最终状态只保留父字段经toState聚合后的单值。
  • 子字段应各自提供toInput从父状态值拆出初值,否则子字段初值为空。
  • 子项建议声明name,它同时作为子字段列表渲染的 key,缺失时按索引复用。