Slate 中如何正确处理自定义元素的反序列化?
我在用 Slate 做一个支持代码块的富文本编辑器,序列化时没问题,但反序列化回来就报错。我试过在 deserialize 函数里加判断,但一遇到 code 类型就直接崩溃。
控制台提示 “Cannot resolve a DOM point from Slate point”,是不是我反序列化的结构写错了?下面是我目前的反序列化逻辑:
const deserialize = el => {
if (el.nodeType === 3) {
return el.textContent;
} else if (el.nodeType !== 1) {
return null;
}
const tagName = el.tagName.toLowerCase();
if (tagName === 'pre') {
return {
type: 'code',
children: [{ text: el.innerText }]
};
}
// ...其他元素处理
}
children结构上。Slate 的 block 元素有个硬性规定:
children数组里的每一项必须包含text属性或者是一个有效的嵌套元素。你现在的写法看着没问题,但问题可能出在两个地方。第一个是
innerText会把换行符给吃掉,导致多行代码变成一行,Slate 在计算 point 位置时就会对不上。第二个是你可能把code类型注册成了void元素,但反序列化时没按 void 的规则处理。给你一个修正版本:
注意我把
nodeType === 3的返回值也改成了{ text: el.textContent },这是 Slate 的标准格式,直接返回纯字符串有时候会出问题。如果你在
createEditor时把code设成了void类型,那还得加个void标记:你可以先打印一下反序列化后的 JSON 结构,确认
children里的每一层都有text字段,这个报错信息基本上都是结构不对导致的。