Quill调用setContents()时自定义属性被删除的问题排查
Quill自定义块属性被移除的原因及解决方法
问题原因
你当前的实现存在两个核心问题:
- 混淆了块级Blot与文本属性的使用方式:你创建的
TestBlot是继承自Block的独立块级元素(对应<testblot>标签),但在Delta中却将testblot作为文本的attributes来设置。Quill的Delta规则中,块级Blot属于嵌入内容,需要以insert: { 自定义blot名: 配置 }的形式存在,而非文本属性。 - 自定义Blot缺少必要的序列化/反序列化逻辑:你的
TestBlot仅定义了blotName和tagName,没有实现create、serialize等核心方法,导致Quill无法正确识别并持久化这个Blot的状态。
解决方法
根据你的需求(给特定块添加识别属性),分两种场景给出解决方案:
场景1:给现有块元素(如<p>)添加自定义属性
如果你不需要新的标签,只是想给默认块添加自定义标识属性,可扩展原生Block并覆盖其格式处理逻辑:
// testblot.blot.ts import Quill from 'quill'; const Block = Quill.import('blots/block'); export class TestBlot extends Block { // 保持原生blotName,覆盖原有Block实现 static blotName = 'block'; static tagName = 'P'; // 从DOM节点读取自定义属性 static formats(node: HTMLElement) { const formats = super.formats(node); if (node.hasAttribute('data-testblot')) { formats.testblot = node.getAttribute('data-testblot') === 'true'; } return formats; } // 应用自定义属性到DOM节点 format(name: string, value: any) { if (name === 'testblot') { if (value) { this.domNode.setAttribute('data-testblot', 'true'); } else { this.domNode.removeAttribute('data-testblot'); } } else { super.format(name, value); } } }
注册后,即可在Delta中正常使用该属性:
const ops = [ { attributes: { testblot: true }, insert: title, }, ]; quillEditorInstance.setContents(ops); // 此时getContents()能正确获取到testblot属性
场景2:创建独立的自定义块级元素(如<testblot>)
如果你确实需要新的块标签,需完善自定义Blot的核心方法,并调整Delta的写法:
// testblot.blot.ts import Quill from 'quill'; const Block = Quill.import('blots/block'); export class TestBlot extends Block { static blotName = 'testblot'; static tagName = 'TESTBLOT'; // 创建DOM节点 static create(value: any) { const node = super.create(value); // 可根据传入value设置属性 if (value) { node.setAttribute('data-testblot', 'true'); } return node; } // 序列化Blot为Delta数据 static value(node: HTMLElement) { return node.hasAttribute('data-testblot') ? true : false; } }
注册后,Delta需按嵌入内容的方式编写:
const ops = [ // 插入自定义块 { insert: { testblot: true } }, // 在块内插入文本 { insert: title }, // 插入换行结束当前块 { insert: '\n' }, ]; quillEditorInstance.setContents(ops);
内容的提问来源于stack exchange,提问作者mneumann
相关产品推荐
相关产品推荐

