React
本指南描述了如何将 Tiptap 与您的 React 项目集成。我们使用 Vite,但其他设置的工作流程应该类似。
创建一个 React 项目(可选)
以一个名为 my-tiptap-project 的新 React 项目开始。 Vite 将设置我们所需的一切。
# 使用 npm 创建项目
npm create vite@latest my-tiptap-project -- --template react-ts
# 或者,使用 pnpm 创建项目
pnpm create vite@latest my-tiptap-project --template react-ts
# 或者,使用 yarn 创建项目
yarn create vite my-tiptap-project --template react-ts
# 进入目录
cd my-tiptap-project安装依赖
接下来,安装 @tiptap/react 包,@tiptap/pm(ProseMirror 库)和 @tiptap/starter-kit,它包括启动时常用的扩展。
npm install @tiptap/react @tiptap/pm @tiptap/starter-kit如果您按照步骤 1 和 2 操作,现在可以通过 npm run dev 启动项目,并在浏览器中打开 http://localhost:3000。
集成 Tiptap
要实际开始使用 Tiptap,我们需要创建一个新组件。我们称其为 Tiptap,并在 src/Tiptap.tsx 中添加以下示例代码。
// src/Tiptap.tsx
import { EditorProvider } from '@tiptap/react'
import { FloatingMenu, BubbleMenu } from '@tiptap/react/menus'
import StarterKit from '@tiptap/starter-kit'
// 定义您的扩展数组
const extensions = [StarterKit]
const content = '<p>Hello World!</p>'
const Tiptap = () => {
return (
<EditorProvider extensions={extensions} content={content}>
<FloatingMenu editor={null}>这是浮动菜单</FloatingMenu>
<BubbleMenu editor={null}>这是气泡菜单</BubbleMenu>
</EditorProvider>
)
}
export default Tiptap重要提示:如果您希望避免使用 Editor 上下文,可以随时使用 useEditor 钩子。
// src/Tiptap.tsx
import { useEditor, EditorContent } from '@tiptap/react'
import { FloatingMenu, BubbleMenu } from '@tiptap/react/menus'
import StarterKit from '@tiptap/starter-kit'
// 定义您的扩展数组
const extensions = [StarterKit]
const content = '<p>Hello World!</p>'
const Tiptap = () => {
const editor = useEditor({
extensions,
content,
})
return (
<>
<EditorContent editor={editor} />
<FloatingMenu editor={editor}>这是浮动菜单</FloatingMenu>
<BubbleMenu editor={editor}>这是气泡菜单</BubbleMenu>
</>
)
}
export default Tiptap将其添加到您的应用中
最后,用我们的新 Tiptap 组件替换 src/App.tsx 的内容。
import Tiptap from './Tiptap'
const App = () => {
return (
<div className="card">
<Tiptap />
</div>
)
}
export default App在子组件中消费编辑器上下文
如果您使用 EditorProvider 来设置您的 Tiptap 编辑器,则现在可以使用 useCurrentEditor 钩子从任何子组件访问您的编辑器实例。
import { useCurrentEditor } from '@tiptap/react'
const EditorJSONPreview = () => {
const { editor } = useCurrentEditor()
return <pre>{JSON.stringify(editor.getJSON(), null, 2)}</pre>
}重要:如果您使用 useEditor 钩子来设置您的编辑器,则此方法无效。
您现在应该在浏览器中看到一个非常基础的 Tiptap 示例。
添加开始或结束插槽
由于 EditorContent 组件是由 EditorProvider 组件渲染的,因此我们现在无法直接定义在编辑器内容之前或之后渲染的位置。为此,我们可以在 EditorProvider 组件上使用 slotBefore 和 slotAfter 属性。
<EditorProvider
extensions={extensions}
content={content}
slotBefore={<MyEditorToolbar />}
slotAfter={<MyEditorFooter />}
/>容器属性
EditorProvider 组件接受一个 editorContainerProps 属性来传递属性到编辑器提供器的容器元素。
<EditorProvider
extensions={extensions}
content={content}
editorContainerProps={{ className: 'editor-container' }}
/>响应编辑器状态变化
要响应编辑器状态变化,您可以使用 @tiptap/react 提供的 useEditorState 钩子。该钩子可用于从编辑器状态中获取信息,而不会导致编辑器组件或其子组件重新渲染。
import { useEditorState } from '@tiptap/react'
function MyEditorComponent() {
// ... 您的编辑器设置代码
const editorState = useEditorState({
editor,
// selector 函数用于选择您想要响应的状态
selector: ({ editor }) => {
if (!editor) return null;
return {
isEditable: editor.isEditable,
currentSelection: editor.state.selection,
currentContent: editor.getJSON(),
// 您可以在这里添加更多的状态属性,如:
// isBold: editor.isActive('bold'),
// isItalic: editor.isActive('italic'),
};
},
});
}优化您的性能
我们建议您访问React 性能指南,以高效集成 Tiptap 编辑器。这将帮助您避免应用规模扩大时可能出现的问题。