在构建基于 ProseMirror 的在线编辑器时,自定义 schema 和 view 可以根据业务需求实现特定功能和样式。下面详细说明如何自定义 ProseMirror 的 schema 和 view,并提供相应的示例代码。
自定义 Schema
Schema 定义了编辑器中允许的文档结构和节点类型。通过自定义 schema,你可以控制哪些元素可以被编辑器处理,以及它们的属性和行为。
自定义 Schema 示例
假设我们希望在编辑器中支持自定义的标题和简单的段落格式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| import { Schema } from "prosemirror-model";
// 定义自定义 schema
const mySchema = new Schema({
nodes: {
doc: { content: "block+" },
paragraph: {
content: "text*",
group: "block",
parseDOM: [{ tag: "p" }],
toDOM() { return ["p", 0]; }
},
heading: {
attrs: { level: { default: 1 } },
content: "text*",
group: "block",
defining: true,
parseDOM: [
{ tag: "h1", attrs: { level: 1 } },
{ tag: "h2", attrs: { level: 2 } }
],
toDOM(node) { return ["h" + node.attrs.level, 0]; }
},
text: { group: "inline" }
}
});
|
在这个 schema 中,我们定义了 paragraph 和 heading 节点,允许在文档中使用段落和标题。标题节点具有一个 level 属性,可以通过 DOM 解析和序列化来处理不同级别的标题。
自定义 View
自定义 view 允许你定义编辑器中节点的呈现方式和交互行为。通过自定义 view,你可以为节点添加特定的样式或交互逻辑。
自定义 View 示例
假设我们希望为标题节点添加一个自定义的样式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
| import { EditorView } from "prosemirror-view";
// 自定义标题节点的 view
function headingView(node, view, getPos) {
let dom = document.createElement("h" + node.attrs.level);
dom.className = "custom-heading";
dom.textContent = node.textContent;
return {
dom,
update(updatedNode) {
if (updatedNode.type !== node.type) return false;
dom.textContent = updatedNode.textContent;
return true;
}
};
}
// 初始化编辑器视图
const view = new EditorView(document.querySelector("#editor"), {
state,
nodeViews: {
heading(node, view, getPos) {
return headingView(node, view, getPos);
}
}
});
|
在这个示例中,我们为 heading 节点创建了一个自定义的 view,使用 headingView 函数为标题节点添加了一个自定义的 CSS 类 custom-heading。通过 update 方法,我们可以更新节点的内容。
总结
通过自定义 schema 和 view,ProseMirror 提供了强大的扩展能力,使得开发者可以根据具体需求定制编辑器的功能和样式。你可以根据项目需求进一步扩展这些基础示例,以实现更复杂的文档结构和交互效果。这样做不仅提高了编辑器的灵活性,还能显著提升用户体验。