:在 Ant Design 表单与表格中集成 Markdown 编辑器)
Refine 自定义输入组件Custom Inputs在 Ant Design 表单与表格中集成 Markdown 编辑器【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine导读本篇指南讲解 Refine 项目中如何在 Ant Design 的Form.Item中嵌入自定义输入组件Custom Inputs。在管理后台、内部工具等 B2B 应用里文章正文、富文本、JSON 文档等数据以纯文本框展示和编辑往往体验不佳此时自定义输入组件就是首选方案。读完本文你将掌握自定义组件必须满足的value/onChange受控协议能够在 Refine 的创建、编辑表单中接入 Markdown 编辑器uiw/react-md-editor并了解其配套的表格渲染与详情页展示方案。完整可运行示例见仓库中的 input-custom 示例。为什么需要自定义输入组件Refine 的 Ant Design 集成基于 Ant Design 官方Form组件体系来接管表单数据原生Input、Select、DatePicker等控件已经能覆盖大多数标量字段。但对部分数据类型用纯文本框进行展示与编辑会带来明显的用户体验问题Markdown 内容需要所见即所得的排版、工具栏与预览JSON 富文本如 draft.js、Quill 等编辑器产物结构复杂难以手工编辑HTML 片段需要可视化编辑器辅助。自定义输入组件正是为这类场景而生。Refine 文档明确指出这类组件既可以用在表单字段中也可以用在表格列中——在表单里负责编辑在表格里负责格式化展示例如将 Markdown 渲染成可读文本。自定义输入组件的受控协议Ant Design 的Form.Item支持放入任意自定义表单项但其约束非常明确这些组件必须能通过自身的value属性被受控并且需要实现onChange回调或通过Form.Item的triggerprop 指定的自定义回调名。也就是说Ant Design 表单通过「注入value 监听onChange」这种受控组件协议与自定义组件通信Form.Item把当前字段值通过valueprop 传入自定义组件用户在组件内修改内容后组件调用onChange(newValue)把新值回传给表单表单再把更新后的值写回数据源结合 Refine 的useForm最终提交到 data provider。因此任何遵循{ value?: T; onChange?: (value: T) void }约定的第三方组件Markdown 编辑器、富文本编辑器、颜色选择器、日期区间组件等都能无缝接入Form.Item。若第三方组件的回调名不是onChange则可以通过Form.Item triggercustomEventName指定要监听的事件名。实战示例为 posts 资源接入 Markdown 编辑器以仓库 input-custom 示例 为例它为posts资源引入uiw/react-md-editor作为 Content 字段的编辑器。该示例的技术栈为 React 19 Ant Design v5 refinedev/antdv6 refinedev/simple-restpackage.json 中明确列出uiw/react-md-editor: ^4.0.8等依赖数据源为https://api.fake-rest.refine.dev。在编辑页edit.tsx集成编辑器编辑页完整代码见 examples/input-custom/src/pages/posts/edit.tsx其核心结构如下import React from react; import { Edit, useForm, useSelect } from refinedev/antd; import { Form, Input, Select } from antd; import MDEditor from uiw/react-md-editor; import type { IPost, ICategory } from ../../interfaces; export const PostEdit () { const { formProps, saveButtonProps, query: queryResult } useFormIPost(); const postData queryResult?.data?.data; const { selectProps: categorySelectProps } useSelectICategory({ resource: categories, defaultValue: postData?.category.id, pagination: { mode: server, }, }); return ( Edit saveButtonProps{saveButtonProps} Form {...formProps} layoutvertical Form.Item labelTitle nametitle rules{[ { required: true, }, ]} Input / /Form.Item Form.Item labelCategory name{[category, id]} rules{[ { required: true, }, ]} Select {...categorySelectProps} / /Form.Item Form.Item labelStatus namestatus rules{[ { required: true, }, ]} Select options{[ { label: Published, value: published, }, { label: Draft, value: draft, }, { label: Rejected, value: rejected, }, ]} / /Form.Item Form.Item labelContent namecontent rules{[ { required: true, }, ]} MDEditor>import { useShow, useOne } from refinedev/core; import { Show, MarkdownField } from refinedev/antd; import { Typography } from antd; // ... export const PostShow () { const { query: queryResult } useShowIPost(); const { data, isLoading } queryResult; const record data?.data; // ... category 数据获取 ... return ( Show isLoading{isLoading} Title level{5}Id/Title Text{record?.id}/Text Title level{5}Title/Title Text{record?.title}/Text Title level{5}Category/Title Text{categoryIsLoading ? Loading... : categoryData?.title}/Text Title level{5}Content/Title MarkdownField value{record?.content} / /Show ); };MarkdownField是refinedev/antd内置的展示型字段组件由 packages/antd/src/components/fields/index.ts 导出。其实现位于 packages/antd/src/components/fields/markdown/index.tsx源码显示它基于react-markdown渲染并默认启用remark-gfm插件以支持GitHub Flavored MarkdownGFMexport const MarkdownField: React.FCRefineFieldMarkdownProps ({ value , }) { return ( ReactMarkdown remarkPlugins{[gfm] as unknown as ReactMarkdown.PluggableList} {value} /ReactMarkdown ); };对应测试见 packages/antd/src/components/fields/markdown/index.spec.tsx它复用了通用的 field 测试集fieldMarkdownTests来验证渲染行为。而在列表页 examples/input-custom/src/pages/posts/list.tsx 中表格通过useTable的tableProps直接铺开Table.Column配合useMany批量解析 category 名称展示「自定义输入同样适用于表格列场景」的用法——只不过示例中对 Markdown 内容选择了在详情页完整渲染列表页聚焦 ID、标题、分类与操作列。底层原理useForm 如何驱动自定义组件Refine 的 Ant Design 集成将useForm与 Ant Design 的Form实例深度绑定。从源码结构看packages/antd 目录下src/hooks/form相关实现useForm会根据resource与actioncreate / edit决定数据请求路径编辑场景下通过useShow/data provider 拉取既有记录并回填到 Ant Design 表单实例通过formProps.onFinish拦截提交将表单值交给 data provider 的create/update方法返回saveButtonProps供Edit/Create的按钮使用并自动处理加载态与提交态。因为字段值的「注入与回收」完全由Form.Item的受控协议完成任何自定义组件只要遵守valueonChange约定就能被useForm无差别接管。这意味着你可以为项目里的任意数据类型定制专属输入组件例如基于 draft.js / Quill 的富文本编辑器面向 JSON 配置的代码编辑器如 CodeMirror、Monaco颜色选择器、图标选择器、坐标拾取器等业务控件。它们与Input在 Refine 表单体系中的角色完全等价既不必修改useForm也无需对 data provider 做额外适配——这是「自定义输入组件」模式在 Refine 中成立的根本原因。小结自定义输入组件是 Refine Ant Design 表单体系的重要扩展点。其核心要点可以归纳为要点说明受控协议组件需支持value注入并调用onChange或用Form.Item trigger指定回调名接入方式直接作为Form.Item的子节点使用无需额外绑定典型场景Markdown、JSON 富文本、HTML 等不适合纯文本框的数据类型编辑流程create / edit 页共用同一Form.Item name...声明规则与配置保持一致展示配套详情页用MarkdownField支持 GFM表格列可自定义 render 格式化参考示例examples/input-custom 完整演示了 Markdown 编辑器的集成掌握了这套模式你就可以在 Refine 应用中自由接入各种第三方编辑器组件为后台内容管理、文档系统等场景提供更友好的编辑体验。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考