Lexical图片处理完整指南:3步跑通上传到预览
【免费下载链接】lexicalLexical is an extensible text editor framework that provides excellent reliability, accessibility and performance.项目地址: https://gitcode.com/GitHub_Trending/le/lexical
在编辑器里写周报时,你大概率想直接在光标处贴入一张架构图——在 Lexical(Meta 开源的可扩展富文本编辑器框架)里,Lexical图片处理靠 ImageNode 节点、命令系统和序列化三个环节完成。本文先跑通“上传→插入→显示”的最短路径,再拆开底层原理。
三步跑通图片插入
- 准备一个文件选择入口:一个隐藏的
<input type="file" accept="image/*">就够,官方 playground 的插入弹窗里“File”模式就是这么做的。 - 用
FileReader.readAsDataURL(file)把选中的文件读成 dataURL 字符串,得到浏览器可直接显示的 src。 - 派发一条命令,把图片节点插进编辑器:
export const INSERT_IMAGE_COMMAND = createCommand('INSERT_IMAGE_COMMAND'); editor.registerCommand( INSERT_IMAGE_COMMAND, (payload) => { // 创建图片节点并插入到当前光标处 $insertNodes([$createImageNode({src: payload.src, altText: payload.altText})]); return true; }, COMMAND_PRIORITY_EDITOR, ); // 文件读取完成后派发命令,图片立即出现在文档中 editor.dispatchCommand(INSERT_IMAGE_COMMAND, {src: dataUrl, altText: '架构图'});执行到这一步,图片会出现在光标所在段落里,后续拖拽、缩放、撤销都走编辑器既有能力。
🖼️ 拆解图片处理原理
ImageNode 如何渲染图片
ImageNode 是 DecoratorNode:createDOM只返回一个空<span>占位,真正的画面由decorate()返回的 React 组件负责,因此你挂什么 UI 都行。官方实现里 decorate 渲染了 ImageComponent,它带拖拽缩放手柄和一个嵌套的题注小编辑器,源码见 ImageNode.tsx 与 ImageComponent.tsx。
命令系统如何隔离 UI 与编辑器
弹窗、工具栏、拖放这些入口不直接操作节点,只调用editor.dispatchCommand(INSERT_IMAGE_COMMAND, payload);注册在编辑器侧的处理器负责$createImageNode+$insertNodes。官方把拖拽图片也收敛成了 DRAGSTART/DROP 命令后派发同一条命令,入口可替换、可测试。完整流程在 ImagesExtension 目录。
图片数据如何保存
保存时 Lexical 会把每个节点序列化成 JSON,你只需定义exportJSON/importJSON这对方法:
exportJSON(): SerializedImageNode { return { ...super.exportJSON(), src: this.getSrc(), // dataURL 或远端 URL altText: this.getAltText(), // width、height、题注一并存入 }; }读回时importJSON调$createImageNode复原节点,图片随文档 JSON 一起持久化,无需额外存储逻辑。
可选的进阶方向
| 方向 | 适用场景 | 关键落点 |
|---|---|---|
| 上传到服务器替代 base64(Lexical图片上传) | 文档要落库、协作者可见,避免 JSON 里塞大段 dataURL | FileReader 后把 File POST 给上传接口,拿到 URL 再派发命令,节点里只存 URL |
| 结合 Cropper.js 裁剪(Lexical图片裁剪) | 封面、头像等固定比例的图片 | 裁剪确认后canvas.toDataURL()得到新 src 再派发命令,节点层零改动 |
| 可缩放响应式预览(Lexical图片预览) | 大图超出容器、需要手动调尺寸 | 参照 ImageComponent 的缩放手柄与 maxWidth 限制,写自己的 decorate 组件即可 |
三条路都不需要改 ImageNode 本身,插入链路始终是同一条命令。
完整参考读三处:节点定义在 ImageNode.tsx,插入命令、弹窗与拖放流程在 ImagesExtension,文档级文件导入导出在 fileImportExport.ts。
【免费下载链接】lexicalLexical is an extensible text editor framework that provides excellent reliability, accessibility and performance.项目地址: https://gitcode.com/GitHub_Trending/le/lexical
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考