React Remirror富文本编辑器:如何实现初始文本可添加不可删除?
解决方案
要实现「初始文本不可删除但允许添加新内容」的需求,不用写过于复杂的逻辑,基于Remirror的扩展机制就能轻松实现。核心思路是给初始内容的节点添加保护标记,在删除操作触发前拦截并判断是否涉及受保护的初始内容,仅阻止对初始内容的删除,不影响用户新增内容的编辑。
步骤1:标记初始内容
给初始内容的节点添加自定义属性(比如protected: true),方便后续识别受保护的内容:
// 定义带有保护标记的初始内容 const initialContent = { type: 'doc', content: [ { type: 'paragraph', attrs: { protected: true }, // 标记该段落为受保护的初始内容 content: [{ type: 'text', text: '这是不可删除的初始文本' }] } ] };
步骤2:编写简易自定义扩展
创建一个轻量的Remirror扩展,监听编辑器的删除操作,拦截对受保护内容的删除:
import { Extension } from 'remirror'; class ProtectedContentExtension extends Extension { get name() { return 'protectedContent' as const; } onCreate() { // 初始化时记录所有受保护节点的位置和尺寸 const protectedNodes = []; this.view.state.doc.descendants((node, pos) => { if (node.attrs.protected) { protectedNodes.push({ pos, nodeSize: node.nodeSize }); } }); this.store.setKey('protectedNodes', protectedNodes); } onBeforeDispatch(tr) { const protectedNodes = this.store.getKey('protectedNodes'); // 仅处理删除类操作 if (!tr.isDelete) return true; const { from, to } = tr.selection; // 判断当前删除范围是否与受保护节点重叠 const touchesProtectedContent = protectedNodes.some(({ pos, nodeSize }) => { const nodeEnd = pos + nodeSize; return from < nodeEnd && to > pos; }); // 如果涉及受保护内容,阻止本次删除操作 return !touchesProtectedContent; } }
步骤3:在编辑器中使用扩展
将自定义扩展与Remirror核心预设一起传入编辑器配置:
import { Remirror, useRemirror } from '@remirror/react'; import { CorePreset } from '@remirror/preset-core'; const ProtectedEditor = () => { const { manager, state } = useRemirror({ content: initialContent, extensions: () => [new CorePreset(), new ProtectedContentExtension()], }); return <Remirror manager={manager} initialContent={state} />; }; export default ProtectedEditor;
方案说明
- 该扩展仅拦截删除受保护初始内容的操作,用户在初始内容后新增的文本可以正常编辑、删除。
- 利用
onBeforeDispatch钩子在操作执行前拦截,比事后恢复内容的方式更流畅,不会出现闪烁问题。 - 标记受保护节点的方式灵活,你可以给任意初始节点添加
protected: true属性(比如多个段落、文本块等)。
内容的提问来源于stack exchange,提问作者Jakub Sapko
相关产品推荐
相关产品推荐

