如何在Formio自定义组件中实例化多个基础Select组件?
复用Formio原生Select组件实现多选择组自定义组件
要在自定义组件里保留Formio Select的完整逻辑(包括多选),核心是直接实例化Formio原生的Select组件,而不是手动渲染下拉框。以下是具体实现方案:
核心思路
自定义组件继承Formio的基础Component类,在组件生命周期中动态创建并挂载多个原生Select组件实例,通过事件监听实现父子组件的数据同步,从而完全复用Select的所有内置功能。
完整代码示例
import { components } from 'formiojs'; // 定义自定义多选择组组件 class MultiSelectGroupComponent extends components.components.base.Component { constructor(component, options, data) { super(component, options, data); // 可通过组件配置动态传入,这里先硬编码示例配置 this.childSelectConfigs = this.component.childSelects || [ { key: 'dayPart', label: '时段', multiple: true, data: { values: [{ label: '上午', value: 'am' }, { label: '下午', value: 'pm' }, { label: '晚上', value: 'night' }] } }, { key: 'weekDay', label: '星期', multiple: true, data: { values: [{ label: '周一', value: '1' }, { label: '周二', value: '2' }, { label: '周三', value: '3' }] } }, { key: 'month', label: '月份', multiple: true, data: { values: [{ label: '一月', value: '1' }, { label: '二月', value: '2' }, { label: '三月', value: '3' }] } } ]; this.childComponents = []; } async init() { await super.init(); // 逐个创建并挂载原生Select组件 for (const config of this.childSelectConfigs) { // 原生Select组件类 const SelectComponent = components.components.select; // 实例化子组件,传递父组件的配置、选项和数据上下文 const child = new SelectComponent({ type: 'select', ...config }, this.options, this.data); await child.init(); // 将子组件DOM挂载到自定义组件容器 this.element.appendChild(child.element); // 监听子组件值变化,同步到父组件 child.on('change', () => this.syncParentValue()); this.childComponents.push(child); } // 初始化父组件值 this.syncParentValue(); } // 同步子组件值到父组件 syncParentValue() { this.value = this.childComponents.reduce((acc, child) => { acc[child.component.key] = child.value; return acc; }, {}); this.emit('change', this.value); } // 父组件值变化时同步到子组件 setValue(value) { super.setValue(value); if (!value) return; this.childComponents.forEach(child => { if (value[child.component.key] !== undefined) { child.setValue(value[child.component.key]); } }); } // 渲染自定义组件容器 render() { this.element = super.render('div', { class: 'multi-select-group d-flex gap-3' }); return this.element; } } // 注册自定义组件到Formio组件库 components.addComponent('multiSelectGroup', MultiSelectGroupComponent);
关键细节说明
- 组件继承与生命周期:继承Formio的
base.Component,确保和原生组件生命周期一致,避免出现渲染或数据同步问题。 - 原生Select实例化:直接使用
components.components.select获取原生Select组件类,传入配置、上下文参数实例化,完整复用多选、搜索、选项过滤等功能。 - 数据同步:通过
change事件监听子组件值变化,实时更新父组件的value;父组件setValue时反向同步到子组件,保证数据一致性。 - 可配置化扩展:如果需要在Formio编辑器中让用户自定义子Select的选项、标签等,可以在自定义组件的schema中添加
childSelects配置字段,替换代码中的硬编码配置。
使用方式
注册组件后,在Formio编辑器中就能找到multiSelectGroup组件,添加到表单后即可使用,其提交数据结构为:
{ "multiSelectGroup": { "dayPart": ["am", "pm"], "weekDay": ["1"], "month": ["2", "3"] } }
内容的提问来源于stack exchange,提问作者Mewster
相关产品推荐
相关产品推荐

