如何从Lexical富编辑器的editorState获取HTML及选择存储格式
Lexical编辑器:HTML vs JSON存储选择及HTML生成/展示方案
存储格式对比与选择
JSON格式(Lexical原生状态)
- 优势:完全保留编辑器的所有原生状态,包括自定义节点、选区细节、特殊样式,后续在Lexical里重新编辑时能100%还原,不会丢任何编辑器特有功能。体积也相对可控,适合需要二次编辑的场景。
- 劣势:不能直接在编辑器外展示,得额外转成HTML才能渲染。
HTML格式
- 优势:拿到就能直接在浏览器或其他支持HTML的地方展示,不用额外解析步骤,适合只看不改的内容。
- 劣势:存的是渲染后的结构,丢了Lexical的原生状态信息,要是后续想在Lexical里重新编辑,把HTML转回去很可能会丢自定义节点或复杂格式,兼容性拉胯。
总结建议
- 要是内容之后还要在Lexical里编辑,优先存JSON,需要展示时再转HTML。
- 要是内容只看不改,直接存HTML就行。
- 也可以两种都存,兼顾编辑和展示,就是多占点存储成本。
实现HTML生成及外部展示
Lexical官方提供了@lexical/html包来做状态和HTML的互转,先装包:
npm install @lexical/html
1. 生成JSON/HTML并存储
修改你的示例代码,加入生成逻辑(注意要拿到Lexical编辑器实例):
import { $generateHtmlFromNodes } from '@lexical/html'; import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'; const EditorWrapper = ({ changeHandler, placeholder, aditionalTools, editorConfig }) => { // 获取Lexical编辑器实例 const [editor] = useLexicalComposerContext(); const handleChange = (editorState) => { // 生成原生JSON状态 const editorJson = editorState.toJSON(); // 生成HTML内容 const editorHtml = editorState.read(() => { return $generateHtmlFromNodes(editor, null); }); // 把数据传给外部处理(比如存数据库) if (changeHandler) { changeHandler({ json: editorJson, html: editorHtml }); } }; return ( <LexicalComposer initialConfig={editorConfig}> <div className="editor-container"> <ToolbarPlugin aditionalTools={aditionalTools} /> <div className="editor-inner"> <RichTextPlugin contentEditable={<ContentEditable className="editor-input" />} placeholder={<Placeholder placeholder={placeholder} />} /> <OnChangePlugin ignoreInitialChange onChange={handleChange} /> </div> </div> </LexicalComposer> ); };
2. 编辑器外部展示HTML
直接渲染存储的HTML
如果存的是HTML,用React的dangerouslySetInnerHTML渲染(一定要做XSS过滤!):
// 先装XSS过滤库:npm install dompurify import DOMPurify from 'dompurify'; const ContentDisplay = ({ htmlContent }) => { // 过滤恶意HTML const sanitizedHtml = DOMPurify.sanitize(htmlContent); return ( <div className="content-display" dangerouslySetInnerHTML={{ __html: sanitizedHtml }} /> ); };
从JSON转HTML再渲染
如果存的是JSON,先转成HTML再渲染:
import { $generateHtmlFromNodes } from '@lexical/html'; import { createEditor, EditorState } from 'lexical'; import DOMPurify from 'dompurify'; // JSON转HTML工具函数 const jsonToHtml = (editorJson) => { const editor = createEditor(); let html = ''; editor.update(() => { EditorState.fromJSON(editor, editorJson); html = $generateHtmlFromNodes(editor, null); }); return DOMPurify.sanitize(html); }; // 使用示例 const StoredContent = ({ storedJson }) => { const displayHtml = jsonToHtml(storedJson); return <ContentDisplay htmlContent={displayHtml} />; };
注意点
- 自定义节点:如果用了Lexical自定义节点,要在
$generateHtmlFromNodes的第二个参数里传自定义节点的HTML转换器,不然转出来的HTML会丢自定义节点的内容。 - XSS风险:不管是直接存HTML还是转出来的HTML,都必须做过滤,别让恶意脚本跑起来。
内容的提问来源于stack exchange,提问作者Rupinderpal Thind
相关产品推荐
相关产品推荐

