---
title: "Svelte"
description: "了解如何使用 Svelte 设置 Tiptap，以实现动态富文本编辑体验。请查看我们文档中的详细指南！"
canonical_url: "https://tiptap.zhcndoc.com/editor/getting-started/install/svelte"
---

# Svelte

了解如何使用 Svelte 设置 Tiptap，以实现动态富文本编辑体验。请查看我们文档中的详细指南！

了解如何使用本分步指南将 Tiptap 集成到您的 SvelteKit 项目中。或者，查看我们的 [Svelte 文本编辑器示例](https://tiptap.zhcndoc.com/examples/basics/default-text-editor.md)。

## 走捷径：带 Tiptap 的 Svelte REPL

如果您想立即开始，这里有一个 [带 Tiptap 的 Svelte REPL](https://svelte.dev/playground/66be82691d304dc981502659e93f8b92)。

### 先决条件

- 您的机器上安装了 [Node](https://nodejs.org/en/download/)
- 具备使用 [Svelte](https://svelte.dev/docs#getting-started) 的经验

## 创建项目（可选）

如果您已经有一个 SvelteKit 项目，那也很好。只需跳过此步骤。

为了本指南的目的，从一个名为 `my-tiptap-project` 的全新 SvelteKit 项目开始。以下命令将设置我们所需的一切。它会问很多问题，但请选择您喜欢的选项或使用默认设置。

```bash
npm create svelte@latest my-tiptap-project
cd my-tiptap-project
npm install
npm run dev
```

### 安装依赖

既然我们已经完成了样板代码，让我们安装 Tiptap！在以下示例中，您需要 `@tiptap/core` 包，以及一些组件、`@tiptap/pm` 和 `@tiptap/starter-kit`，它们包括了最常用的扩展，以便快速入门。

```bash
npm install @tiptap/core @tiptap/pm @tiptap/starter-kit @tiptap/extension-bubble-menu
```

如果您完成了步骤 1 和 2，现在可以使用 `npm run dev` 启动您的项目，并在您喜欢的浏览器中打开 [http://localhost:3000/](http://localhost:3000/)。如果您正在处理现有项目，这可能会有所不同。

## 集成 Tiptap

要开始使用 Tiptap，您需要向您的应用添加一个新组件。我们称之为 `Tiptap`，并在 `src/lib/Tiptap.svelte` 中添加以下示例代码。

这是让 Tiptap 在 SvelteKit 上快速启动和运行的最快方法。它将为您提供一个非常基本的 Tiptap 版本，没有任何按钮。别担心，您将很快能够添加更多功能。

```svelte
<script>
  import { onMount, onDestroy } from 'svelte'
  import { Editor } from '@tiptap/core'
  import { StarterKit } from '@tiptap/starter-kit'
  import BubbleMenu from '@tiptap/extension-bubble-menu'

  let bubbleMenu = $state()
  let element = $state()
  let editorState = $state({editor: null})

  onMount(() => {
    editorState.editor = new Editor({
      element: element,
      extensions: [
        StarterKit,
        BubbleMenu.configure({
          element: bubbleMenu,
        }),
      ],
      content: `
        <h1>Hello Svelte! 🌍️ </h1>
        <p>This editor is running in Svelte.</p>
        <p>Select some text to see the bubble menu popping up.</p>
      `,
      onTransaction: ({ editor }) => {
        // 更新状态信号以强制重新渲染
        editorState = { editor }
      },
    })
  })
  onDestroy(() => {
    editorState.editor?.destroy()
  })
</script>

<div style="position: relative" class="app">
  {#if editorState.editor}
    <div class="fixed-menu">
      <button
        onclick={() => editorState.editor.chain().focus().toggleHeading({ level: 1 }).run()}
        class:active={editorState.editor.isActive('heading', { level: 1 })}
      >
        H1
      </button>
      <button
        onclick={() => editorState.editor.chain().focus().toggleHeading({ level: 2 }).run()}
        class:active={editorState.editor.isActive('heading', { level: 2 })}
      >
        H2
      </button>
      <button onclick={() => editorState.editor.chain().focus().setParagraph().run()} class:active={editorState.editor.isActive('paragraph')}>
        P
      </button>
    </div>
  {/if}

  <div bind:this={element}></div>
</div>

<style>
  button.active {
    background: black;
    color: white;
  }
</style>

```

## 将其添加到您的应用中

现在，让我们将 `src/routes/+page.svelte` 的内容替换为以下示例代码，以在我们的应用中使用新的 `Tiptap` 组件。

```svelte
<script>
  import Tiptap from '$lib/Tiptap.svelte'
</script>

<main>
  <Tiptap />
</main>
```

Tiptap 现在应该在您的浏览器中可见。祝贺您，给自己一个赞吧！ :)

## 后续步骤

- [配置您的编辑器](https://tiptap.zhcndoc.com/editor/getting-started/configure.md)
- [为编辑器添加样式](https://tiptap.zhcndoc.com/editor/getting-started/style-editor.md)
- [了解更多 Tiptap 概念](https://tiptap.zhcndoc.com/editor/core-concepts/introduction.md)
- [学习如何持久化编辑器状态](https://tiptap.zhcndoc.com/editor/core-concepts/persistence.md)
- [开始构建您自己的扩展](https://tiptap.zhcndoc.com/editor/extensions/custom-extensions.md)

## 使用 Svelte 传统语法的设置

上面的示例使用了 [Svelte 符号语法](https://svelte.dev/docs/svelte/what-are-runes)。如果您的 Svelte 应用处于 [传统模式](https://svelte.dev/docs/svelte/legacy-let)，请改用以下代码为 `Tiptap.svelte` 组件。

```svelte
<script>
  import { onMount } from 'svelte';
  import { Editor } from '@tiptap/core';
  import StarterKit from '@tiptap/starter-kit';

  let element;
  let editor;

  onMount(() => {
    editor = new Editor({
      element: element,
      extensions: [StarterKit],
      content: '<p>Hello World! 🌍️ </p>',
      onTransaction: () => {
        // 强制重新渲染，以便 `editor.isActive` 按预期工作
        editor = editor;
      },
    });

    return () => {
      if (editor) {
        editor.destroy();
      }
    }
  });
</script>

{#if editor}
  <button
    on:click={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
    class:active={editor.isActive('heading', { level: 1 })}
  >
    H1
  </button>
  <button
    on:click={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
    class:active={editor.isActive('heading', { level: 2 })}
  >
    H2
  </button>
  <button
    on:click={() => editor.chain().focus().setParagraph().run()}
    class:active={editor.isActive('paragraph')}
  >
    P
  </button>
{/if}

<div bind:this={element} />

<style>
  button.active {
    background: black;
    color: white;
  }
</style>
```
