富文本字段和 Markdown 字段在后台表单里的问题,本质上很像,真正麻烦的都不是"能不能挂进去",而是挂进去以后尺寸、回显、校验和展示边界是否稳定。放到 md-editor-v3 之后,最常见的问题通常集中在编辑区高度不合适、宽度被表单栅格压缩、列表页直接把大段 Markdown 原文露出来,以及空字符串、空格、空行这类内容没有被正确拦住。
这篇内容围绕 fast-crud + md-editor-v3 这一段 Markdown 字段配置展开,重点拆开 content_md 的字段定义、column 与 form 的职责边界、form.col.span 与 component.style.height 的尺寸控制方式,以及 Markdown 字段在后台表单里常见的校验、回显和展示处理。重点不放在 Markdown 编辑器原理,而放在后台 CRUD 表单里真正高频的几个问题:怎么放、怎么控、怎么拦、怎么维护。
文章目录
需求解析
当前场景对应的是后台表单中的 Markdown 编辑器字段,运行语境可以明确放在 fast-crud + md-editor-v3 体系内。目标不是单纯把组件渲染出来,而是让它在新增、编辑、弹窗、抽屉、详情查看这些场景里都保持相对稳定的尺寸和行为。
Markdown 字段和富文本字段最大的不同在于数据形态。富文本编辑器提交的是 HTML 片段,而 md-editor-v3 提交的通常就是 Markdown 原文字符串,所以在值回显和提交链路上会更直接。但这并不代表它就没有配置问题。真正高频的问题仍然集中在几个位置:
- 宽度实际上由表单栅格决定,而不是编辑器自己决定
- 高度如果没有单独控制,编辑体验很容易失衡
- 列表页误展示大段 Markdown 文本,会直接破坏列表可读性
- 空内容如果只做简单必填,空格和空行仍然可能漏过去
- Markdown 存储和详情页渲染是两个层,不应该混成一个问题
也就是说,这类字段真正要解决的不是"怎么接组件",而是"怎么把一个 Markdown 编辑器字段放进 CRUD 表单体系后,仍然保持职责清晰"。
数据处理
编辑器实例
表单承载
字段定义
Markdown 字段接入
声明字段名称
指定组件类型
配置列表展示
设置表单栅格
绑定默认值或显示状态
设置校验规则
控制编辑器高度
配置占位提示
处理禁用或只读状态
值回显
字符串提交
详情页渲染
从这条链路看,Markdown 编辑器的宽度控制落在 form.col.span 这一层,高度控制落在 component.style.height 这一层,列表展示则完全属于 column 层。几个问题分别属于不同的配置块,如果把它们混在一起处理,通常就会出现"改了不生效"或者"以为是编辑器问题,结果其实是表单布局问题"的情况。
功能实现
这里直接以一个典型的 md-editor-v3 字段为例,目标是把 Markdown 编辑器完整挂进 FastCRUD 表单,并把宽度、高度、校验和回显放到正确层级。
ts
content_md: {
title: "Markdown内容",
type: "md-editor-v3",
column: {
show: false,
width: 300
},
form: {
col: { span: 24 },
rules: [
{
validator: async (rule, value) => {
if (!value || !value.trim()) {
throw new Error("内容不能为空");
}
},
trigger: "blur"
}
],
component: {
style: {
height: "600px"
},
placeholder: "请输入 Markdown 内容"
}
}
}
这一段结构看起来不复杂,但几个关键点必须拆开理解。
type: "md-editor-v3" 决定当前字段使用 Markdown 编辑器组件。这里的组件类型只负责"用什么编辑器",不负责宽度和高度的完整布局。真正影响显示区域大小的,是后面的表单层和组件层配置。列表列配置里的 column.width 和 column.show 只属于列表页,不参与编辑区尺寸控制。width: 300 的作用是控制表格列宽,而不是控制编辑器本体宽度;show: false 的作用是避免正文在列表页直接铺开。Markdown 内容通常较长,还会带标题、代码块、列表和表格,如果放在列表里直接展示,页面会非常乱,所以这一层通常默认就是不展示正文。
字段顶层配置本身承担的是字段元信息和数据构建职责,适合抽成统一说明表。
| 参数路径 | 参数名 | 类型 | 作用说明 | 典型用途 |
|---|---|---|---|---|
content_md |
title |
string |
字段显示名称 | 表单标题、详情标题 |
content_md |
type |
string |
使用的组件类型 | 固定为 md-editor-v3 |
content_md |
valueBuilder |
function |
回显前值处理 | 编辑前格式整理 |
content_md |
valueResolve |
function |
提交前值处理 | 提交前清洗字符串 |
列表列配置只服务于列表展示,不解决 Markdown 编辑器尺寸问题。
| 参数路径 | 参数名 | 类型 | 作用说明 | 典型用途 |
|---|---|---|---|---|
column |
show |
boolean |
是否在列表中显示 | 正文一般设为 false |
column |
width |
number |
列宽 | 摘要展示 |
column |
formatter |
function |
格式化显示内容 | 截断 Markdown 文本 |
column |
ellipsis |
boolean |
超出省略 | 避免列表过长 |
column |
align |
string |
列对齐方式 | 左对齐或居中 |
Markdown 字段真正的宽度控制在表单层。比如:
ts
form: {
col: { span: 24 }
}
这里的 span: 24 表示该字段占满整行。如果改成 12,那它只占半行。编辑器看起来"太窄",通常不是 md-editor-v3 本身的问题,而是表单栅格只给了它一半空间。
所以表单层配置才是宽度的实际落点。
| 参数路径 | 参数名 | 类型 | 作用说明 | 典型用途 |
|---|---|---|---|---|
form |
show |
`boolean | computed` | 是否显示字段 |
form |
value |
string |
默认值 | 新建时填充模板 |
form |
readonly |
`boolean | computed` | 只读状态 |
form |
helper.text |
string |
字段说明 | 提示支持 Markdown 语法 |
form.col |
span |
number |
栅格宽度 | 24 最常用 |
form.col |
style |
object |
栅格样式 | 留白和间距控制 |
接下来是高度控制。Markdown 编辑器的高度一般不放在顶层,也不依赖表格列配置,而是放在组件层:
ts
component: {
style: {
height: "600px"
}
}
这个位置控制的是编辑器可视区域高度。弹窗表单里如果不显式控制高度,编辑器区域经常会偏小;单页编辑模式下如果高度过低,长文档编辑体验会很差。也就是说,高度属于组件层,而不是表单栅格层。
| 参数路径 | 参数名 | 类型 | 作用说明 | 典型用途 |
|---|---|---|---|---|
component |
style.height |
string |
编辑器可视高度 | 控制编辑区域高度 |
component |
placeholder |
string |
占位提示 | 引导输入 Markdown |
component |
disabled |
`boolean | computed` | 是否禁用 |
component |
preview |
boolean |
是否启用预览 | 结合组件能力决定 |
component |
toolbars |
array |
工具栏配置 | 精简工具项 |
Markdown 字段的校验相对直接,因为它本质上是字符串,不像富文本那样会生成 <p><br></p> 这种 HTML 空壳。但这不代表 required: true 就一定够用。因为用户仍然可能只输入空格或者空行。
更稳的写法还是自定义校验:
ts
rules: [
{
validator: async (rule, value) => {
if (!value || !value.trim()) {
throw new Error("内容不能为空");
}
},
trigger: "blur"
}
]
这样可以把空字符串、空格和只有空行的内容一并拦掉。
| 参数路径 | 参数名 | 类型 | 作用说明 | 典型用途 |
|---|---|---|---|---|
rules[] |
required |
boolean |
是否必填 | 强制填写内容 |
rules[] |
message |
string |
错误提示 | 校验失败反馈 |
rules[] |
validator |
function |
自定义校验 | 拦截空格和空行 |
rules[] |
trigger |
string |
触发时机 | blur / change |
值处理这一层是 Markdown 编辑器和富文本编辑器差别最大的地方。md-editor-v3 提交的通常就是 Markdown 原文字符串,所以回显和提交链路相对简单:
- 数据库存的是 Markdown 字符串
- 表单回显时直接回填这个字符串
- 提交时继续把字符串传给后端
- 真正渲染 HTML 的动作放在详情页或前台展示层
也就是说,Markdown 存储和 Markdown 渲染是两个阶段,不建议混成一个字段问题处理。如果详情页需要渲染效果,应该在展示层再用 Markdown 渲染器把内容转成 HTML,而不是在编辑时就把字段存成 HTML。
这一层也可以抽成一个简化理解链路:
数据库中的 Markdown 字符串
FastCRUD 表单回显
md-editor-v3 编辑
提交字符串到后端
详情页渲染为 HTML
如果把整个字段装配过程串起来看,Markdown 字段的维护重点其实可以归到四个问题:列表是否展示正文、表单给了多大宽度、组件给了多高高度、提交前有没有做空内容校验。这些点分别属于 column、form、component 和 rules 四个层次,不应该揉成一个"编辑器问题"。
对于工程维护来说,Markdown 字段还有一组常见但不一定第一眼就会配到的补充参数,也值得顺手整理出来。
| 参数 | 作用 |
|---|---|
valueChange |
监听 Markdown 内容变化 |
keepAlive |
tab 切换保持编辑器状态 |
clearable |
切换表单时清空内容 |
readonly |
详情模式只读展示 |
helper.text |
给编辑人员提示 Markdown 规范 |
如果只是想要一套能直接用的最小稳定配置,可以收敛成这样:
ts
content_md: {
title: "教程内容",
type: "md-editor-v3",
column: {
show: false
},
form: {
col: { span: 24 },
helper: {
text: "支持 Markdown 语法,可输入标题、列表、代码块、表格等内容"
},
rules: [
{
validator: async (rule, value) => {
if (!value || !value.trim()) {
throw new Error("内容不能为空");
}
},
trigger: "blur"
}
],
component: {
style: {
height: "600px"
},
placeholder: "请输入教程内容"
}
}
}
放到后台教程、帮助文档、接口说明这类场景里,基本已经够用。
总结
这组 md-editor-v3 字段配置的关键,不在于参数有多少,而在于把字段元信息、列表展示、表单栅格、编辑器尺寸和内容校验放到各自正确的层级里。结构理顺之后,宽度控制看 form.col.span,高度控制看 component.style.height,正文是否出现在列表里看 column.show,空内容能不能拦住则看 rules.validator。
Markdown 编辑器在后台表单里的问题通常都比较集中:宽度不够、编辑区过矮、正文误上列表、空格内容漏判。解决思路本身并不复杂,关键是不要把这些问题都误归到编辑器本体上。表单层、组件层、展示层、提交层各自负责一段,问题定位才会快,后续维护也更稳定。
落到后台系统实践里,这类字段规范的意义并不是"参数更全",而是遇到弹窗高度异常、列表展示混乱、详情渲染边界不清、校验失效这些问题时,可以直接定位到正确配置层。这样处理之后,Markdown 字段就不只是能用,而是能比较稳定地长期维护。