告别写死选项!Unione Form Editor 自定义单选框组件|支持字典/接口动态加载
告别写死选项!Unione Form Editor 自定义单选框组件|支持字典/接口动态加载

绝大多数低代码单选框,都卡在「选项写死」
做业务表单开发,单选框是使用频率最高的基础组件之一:状态选择、类型分类、业务判定、开关选项,几乎每个表单都离不开。
但很多开源低代码平台的原生单选框,都有一个致命短板:
只能手动写死固定选项,不支持动态加载、不支持数据联动、不支持后台字典/接口回显。
一旦业务选项需要变更、需要根据上游字段联动、需要对接业务字典,就必须改代码、发版本,完全达不到「低代码快速迭代」的初衷。
今天给大家拆解 Unione Form Editor 自研高级单选框组件,区别于普通静态单选,原生支持动态选项加载、字段联动、事件脚本、横竖布局、提示注释,是真正可落地企业复杂业务的单选组件。
Unione 单选框组件|核心能力亮点
这不是一个普通单选框,是一套动态数据选择解决方案:
✅ 双布局自由切换:横向横向排版 / 竖向列表排版,适配所有表单样式
✅ 动态选项引擎:支持静态选项、字典、接口、数据集四种来源
✅ 表单字段联动:支持依赖其他表单字段,联动刷新选项
✅ 选项提示注释:每个选项可配置帮助说明,hover 悬浮展示
✅ 自定义选择事件:支持 JS 脚本,选中后触发自定义业务逻辑
✅ 智能数据转换:自动类型统一、回填、回显,适配后端数据格式
✅ 防抖刷新机制:字段频繁变更不重复请求,性能更稳定
一、全套源码逐段解析(Vue3+TS 企业级封装)
1. 模板层:简洁优雅,自带提示+动态渲染
模板采用 Ant Design 原生单选组件二次封装,自动遍历选项、支持悬浮帮助提示、布局动态绑定,UI 简洁且业务能力拉满。
<template>
<a-radio-group :class="['unione-form-radio',layout]" v-model:value="modelValue">
<template v-for="option in selectOptions" :key="option.value">
<a-radio :value="option.value" @click="handleSelect(option)">
<span>{{option.label}}</span>
<a-tooltip :title="option.help" v-if="option.help">
<QuestionCircleOutlined class="icon"/>
</a-tooltip>
</a-radio>
</template>
</a-radio-group>
</template>
模板核心亮点:
- 动态绑定布局 class,一键切换横/竖排版;
- 原生支持选项帮助提示,复杂选项可备注说明,提升用户填报体验;
- 每一次选择触发自定义事件,留给脚本拓展空间。
2. 核心逻辑层:动态加载+联动+转换器引擎(重点)
这是该组件碾压普通单选框的核心:内置 Unione 专属转换器、字段监听、参数回填、动态刷新机制,完整支撑企业级动态数据场景。
<script setup lang="ts">
import { computed,watch, onMounted, ref } from 'vue'
import type { PropType } from 'vue'
import type { WidgetModel } from '../../typing'
import Convertor from '../../lib/convertor'
import { utils } from 'unione-base-vue'
import useDebounce from '../../lib/debounce'
import { useUfeApi } from '../../lib/ufeApi'
// 组件属性定义
const props = defineProps({
wid: {
type: String,
required: false
},
engine: {
type: Object,
required: false
},
widget: {
type: Object as PropType<WidgetModel>,
required: false
},
convert: {
type: Object,
required: false
},
options: {
type: Array,
required: false
},
formValue:{
type:Object
},
layout:{
type:String,
default:'horizontal' //vertical,horizontal
}
})
const modelValue = defineModel<string | number>('value')
// 选项处理
const convertOptions = ref([])
const selectOptions = computed<any>(() => {
if (convertOptions.value?.length) {
return convertOptions.value
}
if (props.options?.length) {
return props.options
}
return []
})
// 引用Value
const refValue = computed(()=>{
const convert = widgetObj.value.convert || props.convert || {}
if(convert.refValue){
const fieldValue:any={}
const fieldNames=convert.refValue.split(',')
fieldNames.forEach((field:string)=>{
const tmp=field.split('=')
if(tmp.length==1){
fieldValue[tmp[0]]=utils.obj.getValue(props.formValue,tmp[0])
}else{
fieldValue[tmp[0]]=utils.obj.getValue(props.formValue,tmp[1])
}
})
console.log(widgetObj.value.name+' ref field:'+convert.refValue+',ref value',fieldValue)
return fieldValue
}
return {};
})
const convertPrams=ref<any>()
onMounted(() => {
// 转换器参数处理
const convert = widgetObj.value.convert || props.convert || {}
convertPrams.value={...(convert.params||{})}
convert.params={...convertPrams.value}
convert.params.body={...(convertPrams.value.body||{}),...refValue.value}
// 加载选项
convertor.value.load(modelValue.value || widgetObj.value.value).then((options: any) => {
convertOptions.value = options
})
})
// 组件定义
const widgetEvent = ref<any>({})
const widgetObj = computed(() => {
const widget = props.engine?.widget(props.wid) || props.widget || {}
// 组件事件处理
if (widget.event) {
Object.keys(widget.event).forEach((eName: string) => {
const eventObj = widget.event[eName]
if (!eventObj) {
return
}
widgetEvent.value[eName] = null
if (typeof eventObj === 'function') {
widgetEvent.value[eName] = eventObj
} else if (eventObj.enable && eventObj.scriptText) {
widgetEvent.value[eName] = new Function('value', 'ctx', eventObj.scriptText)
}
})
}
return widget
})
const ufeApi = useUfeApi()
/**
* 转换器
* 1、字典:dict
* 2、接口:rest
* 3、数据集:dbtable
*/
const convertor = computed(() => {
const convert = widgetObj.value.convert || props.convert || {}
return new Convertor(convert)
})
watch(()=>modelValue.value,()=>{
if(modelValue.value){
modelValue.value=modelValue.value+''
}
})
// 监听转换器变化,重新加载选项
watch(()=>widgetObj.value.convert || props.convert || {},useDebounce(() => {
convertor.value.load().then((options: any) => {
convertOptions.value = options
})
}),{deep:true})
watch(()=>refValue.value,()=>{
console.log(widgetObj.value.name+' ref value changed',refValue.value)
if(refValue.value){
const convert = widgetObj.value.convert || props.convert || {}
convert.params={...convertPrams.value}
convert.params.body={...(convertPrams.value.body||{}),...refValue.value}
convertor.value.load(undefined,true).then((options: any) => {
convertOptions.value = options
})
}
},{deep:true})
function handleSelect(option:any){
if(widgetEvent.value?.select){
widgetEvent.value.select.call(ufeApi,option.value,{
option,
formValue:props.formValue
})
}
}
</script>
核心逻辑深度解读
1. 多层选项优先级机制
组件内置优先级:动态转换选项 > 后台静态配置选项,自动适配字典、接口、数据集数据源,无需改代码切换。
2. 跨字段联动能力
支持绑定表单其他字段作为参数,上游字段改变,自动重载单选选项,完美适配「分类联动二级选项」场景。
3. 自定义脚本事件
选中单选框可执行自定义 JS 脚本,实现赋值、弹窗、显隐、赋值、校验等任意业务逻辑。
4. 防抖高性能更新
参数频繁变更不会频繁请求,防抖处理,保证表单流畅度。
5. 智能数据格式化
自动统一值类型,解决前后端类型不一致导致的回显失效问题。
3. 样式层:双布局适配,简洁统一
<style scoped lang="less">
.unione-form-radio {
&.vertical {
display: flex;
flex-direction: column;
}
.icon{
margin-left: 2px;
}
}
</style>
极简样式设计,横向适合短选项、竖向适合多选项,和平台整体 UI 风格完全统一。
二、组件接入方式
延续 Unione 低代码极简扩展理念:
1. 引入组件源码;
2. 全局注册自定义组件;
3. 表单设计器直接拖拽使用。
接入后完整支持平台所有能力:数据联动、显隐规则、表单校验、权限控制、打印导出、多端适配。
三、业务落地价值
✅ 彻底告别硬编码选项:后台配置字典、接口动态渲染,改业务不用改代码
✅ 支持级联联动场景:分类、状态、业务类型多级联动,适配复杂台账系统
✅ 可拓展业务逻辑:选中即可触发自定义脚本,实现复杂交互
✅ 适配工业级表单:稳定、防抖、容错、类型兜底,生产系统可用
✅ 零学习成本:Vue3 标准写法,源码清晰,可二次自由拓展
四、Docker 一键部署体验完整引擎
想要体验单选框、二维码、条形码、卡片布局全套自定义组件能力,本地一键私有化部署:
git clone https://gitee.com/unione-cloud/unione-docker.git
cd unione-docker
docker-compose up -d
平台访问地址:http://localhost
默认登录账号/密码:admin / admin
开源仓库地址
表单引擎 unione-form-editor
Gitee:https://gitee.com/unione-cloud/unione-form-editor
GitHub:https://github.com/unione-cloud/unione-cloud
流程引擎 unione-flow-editor
Gitee:https://gitee.com/unione-cloud/unione-flow-editor
GitHub:https://github.com/unione-cloud/unione-form-editor
Unione Cloud 平台主仓库
Gitee:https://gitee.com/unione-cloud/unione-cloud
GitHub:https://github.com/unione-cloud/unione-cloud
Docker一键部署脚本仓库
Gitee:https://gitee.com/unione-cloud/unione-docker
最后想说
真正好用的低代码,不是「能拖拽」,而是能灵活适配业务变化。
普通单选框只能做简单选择,而 Unione 自定义单选组件,凭借动态数据源、字段联动、自定义事件,完全可以支撑企业级复杂表单交互场景。
后续持续更新复选框、下拉选择、级联选择等全套高级自定义组件教程,欢迎点赞收藏关注!
更多推荐



所有评论(0)