Vue3+form-create 流程动态表单:设计器编解码、物理表绑定与运行时预览
Vue3form-create 流程动态表单设计器编解码、物理表绑定与运行时预览文档地址https://ruoyioffice.com源码1·GitHubhttps://github.com/yuqing2026/ruoyi-office源码2·GitCodehttps://gitcode.com/zhouzhongyan/ruoyi-office源码3·Giteehttps://gitee.com/yqzy1688/ruoyi-office微信17156169080备注「RuoYi Office」请假、报销、用印看起来都是“填一张表”可每张表字段都在变。若前端为每张单写死a-form业务一改就要发版。动态表单把设计态收成 JSON运行态用同一套规则渲染。难点不在拖拽好看而在编解码不污染动态默认值、能绑物理表、能脱离设计器预览。本文按 RuoYi Office 的 Vue3 form-create 实现拆开。▲ 拖企业组件 → conf/fields 分存 → 绑 formId 或物理表 → 运行时独立渲染引言拖拽表单为什么在企业里总翻车把开源设计器嵌进后台前两周很爽上线后常见五类故障表象根因后果二次保存后“默认当前用户”变成某个人设计器预览把维护人写进rule.value所有单都显示同一个人审批页打不开设计器包运行时也依赖 FcDesigner包体积和权限都错子表对不上数据库列只存了 JSON没绑物理表保存成功、查询对不齐发起人能改、审批人也能改没有节点字段权限叠加越权改金额改了表单旧流程用旧字段模型没引用 formId或引用了拷贝两套定义分叉所以企业级动态表单要先定契约设计器只产 JSON库里分 conf 和 fields运行时只 decode流程模型只认 formId。一、设计器组件库必须是企业组件流程表单编辑页挂在/bpm/manager/form/edit。中间是画布左侧是基础控件加模板右侧是表单级配置标签宽、必填红星、事件。▲ 效果报销明细用网格排「无 PO 付款、申请部门、报销事项」左侧有金额/时长模板右侧可设标签宽 125px 和事件标准 Input / Select 不够。项目往设计器注入用户选择、部门选择可配默认当前字典选择、地区、上传、富文本、iframe日期/时间的「默认当前」规则appendConfigData显式暴露props.defaultCurrent。useFormCreateDesigner在onMounted里把这些规则挂到 FcDesigner。设计器还开了 AI 配置入口用来辅助生成字段但保存路径仍走同一套编解码避免 AI 产出游离在契约外。全局变量注入流程上下文发起人、节点这样联动公式不用写死用户 ID。二、编解码conf 与 fields 必须分开还要“洗”一遍2.1 为什么不存一整棵 rule 树encodeConf只拿getOption()也就是表单级配置。encodeFields遍历getRule()每个控件编码成一条 JSON 字符串。库表因此是conffields[]而不是一团巨大 JSON。好处字段权限按 field 名叠加时不必解析整棵树单个控件损坏不至于整张表单反序列化失败复制表单可以只改 key不碰 option。exportfunctionencodeConf(designerRef:any){returnformCreate.toJson(designerRef.value.getOption());}exportfunctionencodeFields(designerRef:any){construledesignerRef.value.getRule();constfields:string[][];rule.forEach((item:any){constencodedRulecloneDeep(item);stripDynamicSelectorDefaultValue(encodedRule);fields.push(formCreate.toJson(encodedRule));});returnfields;}2.2 动态默认值不能被预览冻死用户选择器勾了「默认当前用户」后设计器为了让你看见效果会把当前登录人写进rule.value。若原样保存运行时这条静态值会覆盖动态逻辑所有单据发起人都变成表单维护者。functionstripDynamicSelectorDefaultValue(rule:any):any{if(Array.isArray(rule.children)){rule.childrenrule.children.map((child)stripDynamicSelectorDefaultValue(child),);}consttyperule.type||rule._fc_drag_tag;constpropsrule.props||{};if(typeUserSelectprops.defaultCurrentUser){deleterule.value;}if(typeDeptSelectprops.defaultCurrentDept){deleterule.value;}returnrule;}解码时再洗一次并修补 VXE 子表的必填前缀、空选项和行操作按钮。上传控件还要normalizeUploadRule避免旧 JSON 和新上传组件属性对不上。这是动态表单和普通低代码最容易分出高下的点预览态数据不得泄漏进定义。三、物理表绑定让设计器看见真实列有的表单只存 JSON列表里能看到“不绑定物理表”的报销单适合试填和轻流程。要落业务库时必须把主表/明细表列注入设计器全局数据。constschemaObj:Recordstring,any{};for(constcolofmainSchema){if([create_time,creator,deleted,id,tenant_id,update_time,updater].includes(col.column)){continue;}schemaObj[col.column]col.comment||col.column;}globalData.physicalTable{label:主表:${tableName},deletable:false,type:static,result:schemaObj,};审计字段和tenant_id被排除它们由框架填写给业务拖到画布上只会制造脏数据。明细表会再注入physicalDetail并给一行空数据方便子表预览。流程模型通过formId引用这份定义。发起页、审批页、打印页都读同一个 form节点字段权限再叠disabled/hidden/$required。设计器把这三项放进appendConfigData就是为了让节点配置和控件属性对得上。四、运行时详情预览不能加载设计器列表「详情」打开的是运行时form-create不是再开一份 FcDesigner。它getForm后setConfAndFields2再applyDefaultCurrentDateTime。▲ 效果详情弹窗只渲染企业选择器不出现左侧控件库列表同时能区分「不绑定物理表」和普通表单这验证了两条边界设计态和运行态解耦——预览包体小审批页才能嵌进待办企业组件在运行时仍然可用——部门树、用户搜索不是设计器专属。复制表单走typecopy只带copyId保存成新 formId。旧流程继续引用旧定义避免“改一张请假单历史在途全变样”。需要兼容在途时应发新流程版本而不是原地覆盖所有引用。五、和手写业务表单怎么分工动态表单适合字段经常变、审批路径标准的单据。用印外借、财务核销这种有复杂状态机和跨模块回写的项目里仍用手写BasicForm。两者可以共存类型何时用存储流程表单form-create字段多、常改、要运营自助bpm_form.conf/fields自定义业务页强领域规则、多表事务业务模块 Vue SaveReqVO混合头表手写明细或补充项动态formId 业务主键不要用动态表单硬扛总账。它的价值是少发版不是取代领域模型。六、技术亮点设计要点实现方式价值设计运行分离编辑页才加载 FcDesigner审批页轻conf/fields 分存option 与控件数组分开权限和修复都更容易洗动态默认编解码剔除 User/Dept value默认当前用户能活企业组件注入用户/部门/字典/上传能做真审批单物理表列注入跳过审计和租户列绑定真实库formId 引用模型不拷贝 JSON一处改、多流程用详情独立渲染decode form-create验收不进设计器复制出新 IDcopy 不覆盖旧引用在途不被误伤七、快速体验在线演示https://ruoyioffice.com/web/账号 admin / admin123推荐路径流程中心 → 流程设置 → 流程表单打开一张报销或请假表单的编辑页拖一个用户选择器并勾选默认当前保存后再进详情确认运行时没有设计器工具条对比“不绑定物理表”和已绑定主子表的表单看数据绑定面板差异到流程模型里看该 formId 如何被引用。源码仓库GitHubhttps://github.com/yuqing2026/ruoyi-officeGitCodehttps://gitcode.com/zhouzhongyan/ruoyi-officeGiteehttps://gitee.com/yqzy1688/ruoyi-office常见问题FAQ为什么运行时不直接复用设计器组件设计器带控件库、事件面板和 AI 配置体积和权限都不适合嵌进待办。运行时只需要 rule option。默认当前用户为什么会“冻住”预览把当前登录人写进了控件 value。保存前必须删掉只保留defaultCurrentUser开关。不绑定物理表的表单数据存在哪存在流程变量或表单 JSON 里适合轻量收集。要做台账、统计、跨模块回写应绑定物理表或改用手写业务单。改表单会不会影响已经发起的流程模型引用的是 formId。原地保存会让新发起和未加载完的在途一起变。需要隔离时复制表单并升级流程版本。节点字段权限配在哪设计器暴露 hidden / disabled / required真正按节点生效是流程模型的字段权限运行时叠到 fApi 上而不是再存一份表单。结语动态表单的目标不是让运营“随便拖”而是让定义可存、默认值可活、运行时可独立、流程可引用。把编解码和物理表契约做对之后改字段才真正不用发版。想要体验 RuoYi Office 的强大功能在线演示https://ruoyioffice.com/web/账号 admin / admin123源码仓库GitHubhttps://github.com/yuqing2026/ruoyi-office GitCodehttps://gitcode.com/zhouzhongyan/ruoyi-office Giteehttps://gitee.com/yqzy1688/ruoyi-office技术咨询添加微信17156169080备注「RuoYi Office」⭐如果觉得不错请给个 Star 支持一下