react-page 编辑器核心组件 `<Editor />` 完全指南:props 详解、只读/编辑双模式与 JSON 数据格式
前端UI组件【免费下载链接】react-pageNext-gen, highly customizable content editor for the browser - based on React and written in TypeScript. WYSIWYG on steroids.项目地址https://gitcode.com/gh_mirrors/rea/react-page点击查看免费下载Editor /是 react-page基于 React 与 TypeScript 打造的下一代浏览器内容编辑器中第一个需要实例化的组件同时承担内容编辑与内容展示两种职责。本文将以 docs/editor.md 为主线结合 Editor.tsx 源码与 示例应用完整讲解该组件的全部 props、只读与编辑模式切换机制、多语言方案以及底层 JSON 内容格式帮助你直接上手构建自己的可嵌入内容编辑器。组件定位一个组件两种形态react-page 采用单元cell作为内容组织的基本单位而Editor /是所有单元、插件与 UI 控件的容器。官方文档明确指出它既可以用于编辑内容也可以通过设置readOnly为true用于展示内容。最简单的用法是传入一个富文本编辑器插件——react-page 预置了基于 Slate 的slate插件作为cellPlugin同时可选image插件用于上传图片或通过 URL 加载图片。下面的代码取自 simple.tsx演示了最小可运行形态import Editor, { Value } from react-page/editor; import react-page/editor/lib/index.css; // 富文本插件Slate import slate from react-page/plugins-slate; import react-page/plugins-slate/lib/index.css; // 图片展示插件 import image from react-page/plugins-image; import react-page/plugins-image/lib/index.css; // 定义本编辑器可用的插件集合 const cellPlugins [slate(), image]; export default function SimpleExample() { const [value, setValue] useStateValue(null); // 编辑模式 Editor cellPlugins{cellPlugins} value{value} onChange{setValue} /; // 展示模式只读 Editor cellPlugins{cellPlugins} value{value} readOnly /; }从 Editor.tsx 源码可以看到组件默认值定义为readOnly false、value null、onChange null这意味着编辑模式是默认形态。注意这里的slate()需要以函数调用的方式执行Slate 插件工厂会返回一个插件实例而image直接传入即可。编辑与查看的参考示例官方文档为两种形态分别提供了可直接运行的示例页面编辑示例simple.tsx演示valueonChange受控编辑只读示例readonly.tsx演示readOnly展示模式在 readonly.tsx 中内容来自预置的demoSimpleReadOnly样例见 demoSimpleReadOnly.tsx其注释明确提示你通常应该从某个 api / 端点 / 数据库加载这个内容——即只读模式下value往往来自服务端持久化数据。Props 详解value: Value编辑器要展示的内容。该数据可以来自任何来源例如文件、数据库或 API。它是对整页内容的 JSON 表示详见下文 Internal JSON details。官方文档强调这份数据是不透明的opaque在正常情况下不应直接手工修改也不要依赖其内部结构。值得补充的是editor 包入口 还导出了若干与value相关的实用工具便于在受控场景下安全操作内容createValue创建新的内容值migrateValue将旧版本内容迁移到最新 schema配合Migration使用deepEquals深度比较两个内容值objIsNode判断对象是否为合法节点结构。onChange: (newValue: Value) void每当编辑器产生新数据时触发的回调用于把最新内容保存下来。当readOnly为true时该 prop 不是必需的。对应源码位于 callbacks.ts其中还定义了第二个可选回调onChangeLang: (l: string) void在用户切换当前语言时触发可用于同步外部状态。readOnly: boolean设置为true时内容不可编辑适合用于展示场景。官方文档特别强调了它的性能价值只读模式下编辑相关代码根本不会被加载因此在使用 webpack 等打包器时会带来体积缩减。若在运行时把readOnly置回false编辑 UI 会即时加载并显示从而可以在展示与编辑两种模式间无缝切换。这一机制的实现细节非常值得关注。Editor.tsx 通过lazyLoad动态导入EditableEditor而EditableEditor被替换为轻量的HTMLRenderer组件总是以只读方式首次挂载useState(true)useEffect同步官方注释说明这是为了避免 SSR服务端渲染问题——服务端渲染时不会加载任何编辑逻辑当readOnly变化时再决定渲染HTMLRenderer还是EditableEditor即便切换到编辑模式HTMLRenderer仍作为fallback传入保证编辑代码动态加载期间的流畅过渡。官方文档还给出了一个典型实战场景直接在公开页面上提供编辑能力。做法是判断当前用户是否为发布者若是则显示一个按钮点击后把readOnly置为false并提供onChange保存内容——这样展示与编辑共用同一套组件与同一份value。cellPlugins: CellPlugin[]当前编辑器可用的CellPlugin数组。react-page 自带一些内置插件并提供了极强的扩展系统用于创建展示任意内容的自定义插件。通常内置的 slate 插件 非常适合富文本编辑但也可以替换为其他编辑器插件。更多可能性参见内置 Cell 插件自定义 Cell 插件从源码看cellPlugins同时被用于只读渲染与编辑渲染两条路径在 Editor.tsx 中它被放入renderOptions传给HTMLRenderer与EditableEditor两侧。插件数组的顺序会影响工具栏中的展示顺序开发者可以通过CellPlugin的id、title、Renderer、controls如 conditionalForm.tsx 中演示的 autoform 条件表单等字段控制行为。lang当内容需要多语言时传入一个语言 id例如en。需要与languages配合使用。值得注意的是源码中的默认逻辑Editor.tsx 中lang的取值优先级是langprop languages[0].langdefault。也就是说即便不传任何语言配置内容也会被归入default语言键下参见demoSimpleReadOnly中dataI18n.undefined的写法实际为 legacy 的default键。languages一个{lang: string, label: string}数组列出编辑器支持的所有语言const LANGUAGES [ { lang: en, label: English, }, { lang: de, label: Deutsch, }, ];这样编辑用户可以随时选择语言。官方文档强调了这种逐 cell 多语言设计的核心优势任何 cell 默认显示默认语言内容除非为该语言创建了另一个版本。也就是说多语言是按 cell 粒度而非整页粒度进行的用户只需要翻译真正需要翻译的段落避免了传统 CMS把整页复制到另一种语言的痛点。此外单元格还可以按语言隐藏cells can be hidden per language。完整用法可参考 i18n.tsx 示例其中lang取LANGUAGES[0].lang即en并配合languages一起传给Editor /。cellSpacing接受一个数字或{x: number, y: number}对象控制单元格之间的间距cellSpacing { x: 15, // 水平方向单元格间距 y: 20, // 垂直方向单元格间距 };在 Editor.tsx 中cellSpacing的默认值为null即无额外间距并同时参与只读与编辑两条渲染路径的renderOptions。参考实现位于 cellSpacing.tsx该示例通过 AutoForm 动态调节cellSpacingX/cellSpacingY配合 CSS 轮廓.react-page-cell-inner { outline: 1px solid red }可以直观看到间距对网格布局的影响。仓库中customLayoutPluginWithCellSpacing插件则展示了自定义布局插件如何与间距配合。uiTranslator接受(label: string) string类型的函数为编辑器开启 i18n 支持——所有界面标签都会经过该函数包装。对应源码类型定义位于 options.ts注释说明key参数当前是英文翻译文本。官方文档给出的翻译实现来自 i18n 示例如下const TRANSLATIONS: { [key: string]: string } { Edit blocks: 编辑, Add blocks: 添加, Move blocks: 移动, Resize blocks: 调整大小, Preview blocks: 预览模式, }; const uiTranslator useCallback((label?: string) { if (TRANSLATIONS[label] ! undefined) { return TRANSLATIONS[label]; } return ${label}(to translate); }, []);这个实现展示了一个实用技巧未覆盖的标签会回退为${label}(to translate)形式方便在开发期发现缺失的翻译条目。uiTranslator的默认值为null见 defaultOptions.ts即默认不进行翻译。childConstraints实验性接受对象childConstraints: { maxChildren: number, }当编辑器中已有行数少于maxChildren时才显示用于新增 cell 的 () 按钮。官方明确标注其当前限制它目前只控制按钮的显示与否通过拖拽仍然可以添加新 cell后续会被重新设计因此视为实验特性。源码定义见 constraints.ts注释同样标注 EXPERIMENTAL实验性默认值在 defaultOptions.ts 中为{}。更多可选 props源码补充在 options.ts 中还可以看到文档之外、但日常使用频率很高的配置项均可在Editor /上直接传入配置项默认值作用allowResizeInEditMode/allowMoveInEditModetrue/true编辑模式下是否允许调整尺寸 / 拖拽移动单元格zoomEnabled、zoomFactorstrue、[1, 0.75, 0.5, 0.25]是否启用缩放功能及其倍率undoRedoEnabledtrue是否启用撤销 / 重做editEnabled/insertEnabled/layoutEnabled/resizeEnabled/previewEnabled均true侧边栏各功能开关sidebarPositionrightAbsolute侧边栏位置rightAbsolute/rightRelative/leftAbsolute/leftRelativehideEditorSidebarfalse是否隐藏编辑器侧边栏shouldShowErrorInCellsfalse单元格渲染出错时是否在页面显示错误否则仅 console 输出dndBackendHTML5Backend覆盖 react-dnd 的拖拽后端uiThemedefaultTheme自定义 MUI 主题store/middlewarenull/[]传入自定义 Redux store / 中间件未来可能废弃以上默认值均可在 defaultOptions.ts 中逐一核对。内部 JSON 格式详解Internal JSON details整页内容以易于解析的 JSON 形式存储由两部分组成data数据观众实际看到的内容metadata元数据渲染数据所需的辅助信息例如 id、版本、插件信息等。这份 JSON 同样被官方视为不透明结构不应在正常情况下手工编辑。它有以下几个重要特性不包含任何表现层信息——即不存储 CSS可移植JSON 数据可以复制到新文档中从而为版本化或模板化创建当前文档的克隆。优势对比传统富文本编辑器产出的是内容数据与外观样式捆绑在一起的原始 HTML 标记而 JSON 表示更干净、体积小得多且不带观点unopiniated——同一份 JSON 可以用不同的渲染组件以不同的方式呈现。这正是 react-page 能够把编辑与展示分离、并支持自定义渲染器的根基。下面两份 JSON 是官方文档给出的完整示例。示例 1简单文本内容下面这张图展示了该 JSON 渲染出的实际效果一个标题 一段正文{ id: obknih, version: 1, rows: [ { id: b27eia, cells: [ { id: e9htzt, size: 12, plugin: { id: ory/editor/core/content/slate, version: 1 }, dataI18n: { default: { slate: [ { type: HEADINGS/HEADING-TWO, children: [ { text: This is a heading } ] }, { type: PARAGRAPH/PARAGRAPH, children: [ { text: This is some paragraph text } ] } ] } }, rows: [], inline: null } ] } ] }关键结构解读顶层id是内容文档 idversion是内容 schema 版本配合migrateValue做迁移判断rows数组包含一行行内cells数组包含一个占满 12 栅格的 cellsize: 12plugin.id标识该 cell 使用的插件这里是 Slate 富文本plugin.version是插件版本dataI18n是按语言组织的数据——default键下存放默认语言数据若存在其他语言版本会出现对应的语言键如en、dedataI18n.default.slate内部正是 Slate 的节点树HEADINGS/HEADING-TWO、PARAGRAPH/PARAGRAPH等类型节点rows与inline用于嵌套布局如列内再套行、行内元素。对照 demoSimpleReadOnly.tsx 可以看到真实样例数据的结构与上述完全一致只是dataI18n使用 legacy 的undefined键、并在data中携带了对齐信息align: center。示例 2包含图片的内容下图展示了文本行 图片行组合的渲染效果{ id: obknih, version: 1, rows: [ { id: b27eia, cells: [ { id: e9htzt, size: 12, plugin: { id: ory/editor/core/content/slate, version: 1 }, dataI18n: { default: { slate: [ { type: HEADINGS/HEADING-TWO, children: [ { text: This is a heading } ] }, { type: PARAGRAPH/PARAGRAPH, children: [ { text: This is some paragraph text } ] } ] } }, rows: [], inline: null } ] }, { id: 5j8lyl, cells: [ { id: k0t2gk, size: 12, plugin: { id: ory/editor/core/content/image, version: 1 }, dataI18n: { default: { src: https://www.nasa.gov/sites/default/files/styles/full_width/public/thumbnails/image/mars2020-sample-tubes.jpg?itokSiZDKmmG } }, rows: [], inline: null } ] } ] }对比示例 1 可以看出图片 cell 的plugin.id变为ory/editor/core/content/image而dataI18n.default中存放的是图片地址字段src。不同插件在dataI18n中存放的数据形状由插件自身定义——这正是JSON 不带观点、由渲染组件决定呈现方式的体现。图片插件源码位于 image 插件目录其createPlugin.tsx定义了src等字段的 schema 与 Renderer。自定义编辑器 UIcomponents实验性如果需要对编辑器 UI 做更精细的控制可以覆盖部分内部组件。官方文档给出三条重要提醒始终作为最后手段使用Use this always as a last resort因为覆盖后可能无法获得 react-page 的全部功能动手前先提交 Issue说明你究竟想定制或修改什么——很可能存在更简单的解决方案甚至能为 react-page 带来一个新特性从而共享创新目前可替换的组件只有一个BottomToolbar渲染底部工具栏的组件负责展示插件控件和一些单元格操作。如果希望替换更多组件官方欢迎提交 Issue 或 Pull Request 来扩展该列表。对应类型定义位于 components.ts默认值为{}见 defaultOptions.ts。小结与建议的下一步Editor /是整个 react-page 的入口组件一个组件同时覆盖编辑与展示readOnly切换驱动了编辑代码的按需加载cellPlugins决定内容能力边界lang/languages/dataI18n构成逐 cell 粒度的多语言体系cellSpacing控制网格节奏底层 JSON 则保证了内容的可移植性与渲染无关性。上手时建议按以下路径实践从 simple.tsx 开始跑通编辑 →onChange拿到 JSON → 存入数据库的最小闭环用 readonly.tsx 验证只读展示与按需加载结合 i18n.tsx 与 cellSpacing.tsx 熟悉多语言与布局间距深入阅读 内置插件文档 与 自定义 Cell 插件文档按需扩展内容类型若要做服务端渲染或内容迁移参考 server-side-rendering.md 以及 index.tsx 中导出的createValue、migrateValue、deepEquals等工具。赞分享前端UI组件【免费下载链接】react-pageNext-gen, highly customizable content editor for the browser - based on React and written in TypeScript. WYSIWYG on steroids.项目地址https://gitcode.com/gh_mirrors/rea/react-page点击查看免费下载相关推荐JSON Editor数组编辑器完全指南表格、选择器、复选框等多种模式JSON Editor数组编辑器完全指南表格、选择器、复选框等多种模式 JSON Editor是一个强大的基于JSON Schema的编辑器它提供了丰富的数前端UI组件React-Page 编辑器组件深度解析React Page 编辑器组件深度解析 前言 React Page 是一个功能强大的 React 页面构建器它提供了直观的拖放界面来创建和编辑网页内容。本文前端UI组件推荐React Email Editor —— 拖放式邮件编辑器组件推荐React Email Editor —— 拖放式邮件编辑器组件 如果你正在寻找一个强大且开发者友好的视觉邮件构建工具来集成到你的React应用中那么R前端UI组件上一篇SpacetimeDB × Godot 完整教程从零构建可承载数百名玩家的 Blackholio 多人在线游戏下一篇Vant 4 Divider 分割线组件完全指南从基础用法到主题定制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

工业连接场景下M12 5-Pin线缆选型与接线实战指南

工业连接场景下M12 5-Pin线缆选型与接线实战指南

1. 工业连接场景下 M12 5-Pin 线缆的选型逻辑与整体设计思路工业现场布线这件事,外行看就是"一根线",内行看却是一整套关于可靠性、可维护性和成本控制的系统工程。M12 5-Pin Cable for Industrial Connectivity 这个标题,核心落在…

2026/9/25 17:17:33 阅读更多 →
Cursor 设备被锁定后,如何用 TaoToken 统一 Key 通道重建开发环境

Cursor 设备被锁定后,如何用 TaoToken 统一 Key 通道重建开发环境

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 17:17:33 阅读更多 →
Atlas 300V部署YOLOv5全流程实战:从环境搭建到推理优化

Atlas 300V部署YOLOv5全流程实战:从环境搭建到推理优化

最近一段时间,问我“Atlas怎么部署YOLO”的人明显多了起来。我手上刚好有一张Atlas 300V Pro 24G,也就是不少人经常在社区里反复确认的“Atlas 300V 24G是不是运算加速卡”那张卡。项目从买卡、装环境、转模型到把YOLOv5跑出检测框,前前后后折…

2026/9/25 17:17:33 阅读更多 →

最新新闻

OpenClaw iMessage 完整集成指南:从选型到部署

OpenClaw iMessage 完整集成指南:从选型到部署

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 18:06:06 阅读更多 →
Qwen3.5-397B-A17B-FP8 完整 Benchmark 总结:MoE+FP8+TP8 实测与 TaoToken 配置骨架

Qwen3.5-397B-A17B-FP8 完整 Benchmark 总结:MoE+FP8+TP8 实测与 TaoToken 配置骨架

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/25 18:06:06 阅读更多 →
Windows 11 安装 SQL Server 2008 R2 兼容模式全攻略

Windows 11 安装 SQL Server 2008 R2 兼容模式全攻略

1. 为什么要在 Windows 11 上折腾 SQL Server 2008 R2先把话说在前头:SQL Server 2008 R2 是一款发布于 2010 年前后的数据库产品,官方支持早已终止,微软从未将其列为 Windows 11 的兼容目标。那为什么还有人在 Windows 11 上装它&#xff1f…

2026/9/25 18:06:06 阅读更多 →
从 TypeScript 到 C#:现代 SDK 移植的完整实战与踩坑记录

从 TypeScript 到 C#:现代 SDK 移植的完整实战与踩坑记录

把 TypeScript 写的 SDK 原样搬到 C# 里,这事听着简单,做起来全是坑。尤其对象是 Codex SDK 这种带流式响应、事件回调、多环境配置的现代 SDK,不是把interface改成class、把Promise换成Task就完事的。我最近完整做了一遍这个移植&#xff0c…

2026/9/25 18:06:06 阅读更多 →
5G NR通感一体化ISAC系统级模拟器设计:从OFDM波形到距离多普勒处理

5G NR通感一体化ISAC系统级模拟器设计:从OFDM波形到距离多普勒处理

简介:基于5G NR的通信感知一体化(ISAC)系统级模拟器源码工程,面向通信工程、电子信息、人工智能等专业的本科毕业设计或课程设计场景,以Matlab仿真实例完整演示5G新空口框架下的综合传感与通信联合仿真流程与数据分析方…

2026/9/25 18:06:05 阅读更多 →
【项目编号:project62303】Django 电影推荐系统:从电影发现、评分收藏到个性化推荐的完整实现

【项目编号:project62303】Django 电影推荐系统:从电影发现、评分收藏到个性化推荐的完整实现

DJANGO MOVIE RECOMMENDATIONDjango 电影推荐系统:从电影发现、评分收藏到个性化推荐的完整实现以影迷的观影决策路径为主线,连接电影检索、详情数据、用户行为与后台运营技术关键词Django Web业务主线发现 → 互动 → 推荐核心看点多条件筛选 个性化…

2026/9/25 18:05:05 阅读更多 →

日新闻

AI元人文:从工具使用到思维重构的深度探索

AI元人文:从工具使用到思维重构的深度探索

最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决…

2026/9/25 0:00:41 阅读更多 →
Python+CNN车牌识别实战:从数据预处理到模型训练与部署

Python+CNN车牌识别实战:从数据预处理到模型训练与部署

简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据…

2026/9/25 0:00:41 阅读更多 →
Vim基础操作全攻略:保存退出、模式切换与高频命令实战

Vim基础操作全攻略:保存退出、模式切换与高频命令实战

1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保…

2026/9/25 0:00:41 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/24 14:34:13 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/25 11:15:26 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/24 14:33:56 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/24 12:50:34 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/24 14:33:48 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/24 12:49:17 阅读更多 →