表单配置功能使用说明
为什么需要这个功能
过去代码模块如果要接入表单,通常需要把字段、占位文案、接口参数、布局样式都写进 HTML 或 JS。这样做维护成本很高:运营想换一个表单,开发要改代码;字段顺序稍微变化,布局也容易跟着乱。
新的表单配置功能把职责拆开:编辑器负责选择真实表单、控制字段显隐和配置字段布局;代码模块负责把这份配置渲染成最终页面效果。配置只表达“用哪个表单、显示哪些字段、字段如何排布”,不强行绑定最终视觉样式。
所以它不是一个固定样式的表单组件,而是一套配置协议。不同代码模块可以共享同一份表单配置能力,同时保留各自的视觉风格、交互效果和提交逻辑。
整体使用流程
使用时只需要按编辑器里的两个步骤走。第一步完成字段设置,第二步完成布局配置。保存后,主应用会把当前表单、字段、布局和运行时配置合并进代码模块变量 $[fitForm],页面渲染时由代码模块读取。
- 在代码模块配置里打开表单配置弹窗。
- 从左侧表单列表选择一个高级表单。
- 在字段设置中确认表单标题、描述和字段显隐。
- 进入布局配置,使用预设或 24 栅格调整字段排布。
- 点击保存,配置回写到代码模块变量。
字段设置:先决定表单展示哪些内容
字段设置页关注基础信息和字段可见性。左侧是表单列表,右侧展示当前表单的标题、描述以及字段开关。这个阶段不处理最终样式,只解决字段集合和展示范围。
这一页会影响三个核心字段:表单标题写入 form.info.title,表单描述写入 form.info.description,字段显隐写入 field.visible。
最终模块渲染时,应先过滤 field.visible !== false 的字段。被隐藏的字段不应该出现在页面中,也不应该参与提交。
布局配置:再决定字段如何排列
布局配置页使用 24 栅格作为默认坐标系。用户可以先用单列、双列、三列快速预设得到基础结构,再点击画布里的字段微调占据列数、左侧空列和是否另起一行。这样既能快速生成常见布局,也能处理 8/16、6/18、12/12 这类不规则组合。
布局配置保存在 form.layout.fieldLayouts 中。每个字段都有独立布局对象,包含排序、占列、左侧空列和行高等信息。
{
"layout": {
"columns": 24,
"gap": 16,
"fieldLayouts": {
"username": {
"fieldId": "username",
"colSpan": 12,
"offset": 0,
"rowSpan": 1,
"order": 0
}
}
}
}
推荐做法:模块渲染时不要只写 grid-column: span 12。如果字段配置了 offset,应该计算明确起点,例如 grid-column: 4 / span 12,这样才能和编辑器画布保持一致。
最终效果:配置决定结构,模块决定外观
保存后,最终页面不会直接复用编辑器里的控件样式,而是由代码模块读取配置并渲染成自己的视觉效果。字段顺序和占列来自配置,输入框、选项、开关、日期范围、提交按钮等样式则由代码模块统一实现。
配置保存后的数据结构
iframe 保存时会把当前表单、字段、布局和运行时配置返回给主应用。主应用接收后,会合并为 visual_form 配置,并写回代码模块变量。
type FormSavePayload = {
moduleType: "form";
form: Form;
fields: FormField[];
layout: FormLayout;
runtime?: FormRuntimeConfig;
};
代码模块如何接入
新建或改造代码模块时,把变量定义为 input_type: "form"。默认值保持空骨架,等待用户在编辑器里选择真实表单。不要把某个表单 ID 或字段写死在模块里。
[
{
"key": "fitForm",
"label": "高级表单配置",
"input_type": "form",
"default_value": ""
}
]
在 LTD 代码组件中,建议把 $[fitForm] 放进隐藏的 textarea,再由 JS 读取。这样可以避免 JSON 被当成脚本执行。
<div class="demoFormModule" data-ltd-form-module>
<textarea class="demo-form-config" hidden aria-hidden="true">$[fitForm]</textarea>
<form class="demo-form-root"></form>
</div>
<script>
const readFitFormConfig = (container) => {
const node = container.querySelector(".demo-form-config");
const raw = node ? String(node.textContent || "").trim() : "";
if (!raw || raw === "$" + "[fitForm]") return {};
try {
let parsed = JSON.parse(raw);
if (typeof parsed === "string") parsed = JSON.parse(parsed);
return parsed && typeof parsed === "object" ? parsed : {};
} catch (error) {
console.warn("[form module] fitForm parse failed:", error);
return {};
}
};
</script>
渲染字段时,先过滤隐藏字段,再按布局排序,最后根据总列数建立 CSS Grid。下面是最小化的渲染逻辑示例:
const visibleFields = form.fields
.filter((field) => field.visible !== false)
.sort((a, b) => {
const la = form.layout.fieldLayouts[a.id];
const lb = form.layout.fieldLayouts[b.id];
return (la?.order || 0) - (lb?.order || 0);
});
root.style.gridTemplateColumns = `repeat(${form.layout.columns || 24}, minmax(0, 1fr))`;
visibleFields.forEach((field) => {
const layout = form.layout.fieldLayouts[field.id] || { colSpan: 24, offset: 0 };
const start = (layout.offset || 0) + 1;
item.style.gridColumn = `${start} / span ${layout.colSpan || 24}`;
});
请先 登录后发表评论 ~