项目

tiptap 编辑器

引言

Editor 类是 Tiptap 的核心组件之一。它主要负责创建一个功能齐全的 ProseMirror 编辑器,包括创建 EditorView、设置初始 EditorState 等。

方法

编辑器实例会提供一系列公共方法。这些方法是常规函数,可以返回任何类型的数据。它们将帮助你与编辑器进行交互。

不要将方法与 命令混淆。命令用于改变编辑器(内容、选区等)的状态,并且仅返回 truefalse

can()

检查是否可以执行命令或命令链,但不实际执行。这对于启用/禁用按钮或显示/隐藏控件非常有用。

// 检查撤销命令是否可以执行
editor.can().undo();

chain()

创建一个命令链,一次执行多个命令。

// 一次执行两个命令
editor.chain().toggleBold().focus().run();

destroy()

停止编辑器实例并解绑所有事件。

// 拜拜了,宝贝!
editor.destroy();

getHTML()

返回当前编辑器文档作为 HTML。

editor.getHTML();

getJSON()

返回当前编辑器文档作为 JSON。

editor.getJSON();

getText()

返回当前编辑器文档作为纯文本。

参数 类型 描述
options { blockSeparator?: string, textSerializers?: Record<string, TextSerializer>} 选项,用于序列化文本。
// 给我纯文本!
editor.getText();
// 在节点之间添加两个换行符
editor.getText({ blockSeparator: "\n\n" });

getAttributes()

获取当前选中节点或标记的属性。

参数 类型 描述
typeOrName string | NodeType | MarkType 节点或标记的名称
editor.getAttributes("link").href;

isActive()

检查当前选中节点或标记是否活跃。

参数 类型 描述
name string | null 节点或标记的名称
attributes Record<string, any> 节点或标记的属性
// 检查是否为标题
editor.isActive("heading");
// 检查是否为特定级数的标题
editor.isActive("heading", { level: 2 });
// 检查是否具有特定属性值,不管是什么节点/标记
editor.isActive({ textAlign: "justify" });

registerPlugin()

注册一个 ProseMirror 插件。

参数 类型 描述
plugin Plugin 一个 ProseMirror 插件
handlePlugins? (newPlugin: Plugin, plugins: Plugin[]) => Plugin[] 控制如何合并插件到现有插件中

setOptions()

更新编辑器选项。

参数 类型 描述
options Partial 一组选项列表
// 将一个类添加到现有编辑器实例
editor.setOptions({
  editorProps: {
    attributes: {
      class: "my-custom-class",
    },
  },
});

setEditable()

更新编辑器的可编辑状态。

参数 类型 描述
editable boolean true 时,用户应能够向编辑器内输入。
emitUpdate boolean 默认为 true。决定是否触发 onUpdate
// 使编辑器只读
editor.setEditable(false);

unregisterPlugin()

注销一个 ProseMirror 插件。

参数 类型 描述
nameOrPluginKey string | PluginKey 插件的名称

获取器

isEditable

返回编辑器是否可编辑或只读。

editor.isEditable;

isEmpty

检查是否有内容。

editor.isEmpty;

isFocused

检查编辑器是否处于焦点状态。

editor.isFocused;

isDestroyed

检查编辑器是否已销毁。

editor.isDestroyed;

isCapturingTransaction

检查编辑器是否正在捕获事务。

editor.isCapturingTransaction;

设置

element

element 属性指定了编辑器将绑定到的 HTML 元素。以下代码将 Tiptap 与类名为 .element 的元素集成:

import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";

new Editor({
  element: document.querySelector(".element"),
  extensions: [StarterKit],
});

甚至可以在挂载到元素之前初始化编辑器。当 DOM 还不可用时这很有用。只需省略 element,我们会为你创建一个。稍后将其附加到容器中:

yourContainerElement.append(editor.options.element);

extensions

必须在 extensions 属性中传递一个扩展列表,即使你只想允许段落。

import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";
import Document from "@tiptap/extension-document";
import Paragraph from "@tiptap/extension-paragraph";
import Text from "@tiptap/extension-text";
import Highlight from "@tiptap/extension-highlight";

new Editor({
  // 使用默认扩展
  extensions: [StarterKit],

  // ... 或使用特定扩展
  extensions: [Document, Paragraph, Text],

  // ... 或两者都有
  extensions: [StarterKit, Highlight],
});

content

通过 content 属性,你可以提供编辑器的初始内容。这可以是 HTML 或 JSON。

import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";

new Editor({
  content: `<p>示例文本</p>`,
  extensions: [StarterKit],
});

editable

editable 属性决定了用户是否可以向编辑器内输入。

import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";

new Editor({
  content: `<p>示例文本</p>`,
  extensions: [StarterKit],
  editable: false,
});

autofocus

使用 autofocus 可以在初始化时强制光标跳入编辑器。

描述
'start' 将焦点设置到文档开头。
'end' 将焦点设置到文档末尾。
'all' 选择整个文档。
Number 将焦点设置到文档中的特定位置。
true 启用自动聚焦。
false 禁用自动聚焦。
null 禁用自动聚焦。
import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";

new Editor({
  extensions: [StarterKit],
  autofocus: false,
});

enableInputRules

默认情况下,Tiptap 开启所有 输入规则。使用 enableInputRules 可以控制这个行为。

import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";

new Editor({
  content: `<p>示例文本</p>`,
  extensions: [StarterKit],
  enableInputRules: false,
});

另一种方式是只允许特定的输入规则。

import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";
import Link from "@tiptap/extension-link";

new Editor({
  content: `<p>示例文本</p>`,
  extensions: [StarterKit, Link],
  // 传递一个扩展数组或扩展名称
  // 以只允许特定输入规则
  enableInputRules: [Link, "horizontalRule"],
});

enablePasteRules

默认情况下,Tiptap 开启所有 粘贴规则。使用 enablePasteRules 可以控制这个行为。

import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";

new Editor({
  content: "<p>示例文本</p>",
  extensions: [StarterKit],
  enablePasteRules: false,
});

或者,只允许特定的粘贴规则。

import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";
import Link from "@tiptap/extension-link";

new Editor({
  content: "<p>示例文本</p>",
  extensions: [StarterKit, Link],
  // 传递一个扩展数组或扩展名称列表
  // 只允许特定的粘贴规则
  enablePasteRules: [Link, "horizontalRule"],
});

injectCSS

默认情况下,Tiptap 会注入一点点 样式 。通过 injectCSS 可以禁用这个功能。

import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";

new Editor({
  extensions: [StarterKit],
  injectCSS: false,
});

injectNonce

如果你使用了带有 nonce内容安全策略 ,可以指定一个 nonce 值,用于动态创建的元素。例如:

import { Editor } from "@tiptap/core";
import StarterKit from "@tiptap/starter-kit";

new Editor({
  extensions: [StarterKit],
  injectCSS: true,
  injectNonce: "your-nonce-here",
});

editorProps

对于高级用法,你可以通过 editorProps 传递自定义属性,这些将由 ProseMirror 处理。可以用来覆盖各种编辑器事件或改变编辑器 DOM 元素属性,比如添加 Tailwind 类。下面是一个例子:

new Editor({
  // 查看更多信息:https://prosemirror.net/docs/ref/#view.EditorProps
  editorProps: {
    attributes: {
      class:
        "prose prose-sm sm:prose lg:prose-lg xl:prose-2xl mx-auto focus:outline-none",
    },
    transformPastedText(text) {
      return text.toUpperCase();
    },
  },
});

这样可以接入事件处理器,并传递自定义粘贴处理器等。

parseOptions

传入的内容会被 ProseMirror 解析。要参与到解析过程,可以传递 parseOptions ,然后由 ProseMirror 处理。

new Editor({
  // 查看更多信息:https://prosemirror.net/docs/ref/#model.ParseOptions
  parseOptions: {
    preserveWhitespace: "full",
  },
});
在本文档中