以下指南描述了如何将 Tiptap 集成到 Alpine.js 版本 3 中。为了方便演示,我们将使用 Vite 来快速设置项目,但你也可以使用你熟悉的任何工具。Vite 真的非常快,我们非常喜欢它!

要求

创建项目(可选)

如果你已经有一个 Alpine.js 项目,那也没问题,可以跳过此步骤。

在本指南中,我们将从头开始创建一个新的 Vite 项目,命名为 my-tiptap-project。Vite 设置了我们所需的一切,只需选择 Vanilla JavaScript 模板即可。

  1. npm init vite@latest my-tiptap-project -- --template vanilla
  2. cd my-tiptap-project
  3. npm install
  4. npm run dev

安装依赖

好了,模板项目已经准备好,接下来让我们安装 Tiptap!在这个示例中,你需要安装 alpinejs@tiptap/core 包,@tiptap/pm 包,以及 @tiptap/starter-kit,它包含了大多数常见的扩展,可以帮助你快速上手。

  1. npm install alpinejs @tiptap/core @tiptap/pm @tiptap/starter-kit

如果你完成了步骤 1,你可以通过运行 npm run dev 启动项目,并在浏览器中打开 http://localhost:5173。如果你是在现有项目中操作,端口号可能会有所不同。

集成 Tiptap

要开始使用 Tiptap,你需要写一点 JavaScript。我们将以下示例代码放入名为 main.js 的文件中。

这是将 Tiptap 与 Alpine.js 配合使用的最快方式。它将为你提供一个非常基本的 Tiptap 版本。不用担心,稍后你可以添加更多功能。

  1. import Alpine from 'alpinejs'
  2. import { Editor } from '@tiptap/core'
  3. import StarterKit from '@tiptap/starter-kit'
  4. document.addEventListener('alpine:init', () => {
  5. Alpine.data('editor', (content) => {
  6. let editor // Alpine 的响应式引擎会自动将组件属性包装在代理对象中。如果你尝试使用代理的 editor 实例来应用事务,它将导致 "Range Error: Applying a mismatched transaction" 错误。因此,确保使用 Alpine.raw() 来解包它,或者像本示例中那样避免将 editor 存储为组件属性。
  7. return {
  8. updatedAt: Date.now(), // 强制 Alpine 在选择发生变化时重新渲染
  9. init() {
  10. const _this = this
  11. editor = new Editor({
  12. element: this.$refs.element,
  13. extensions: [StarterKit],
  14. content: content,
  15. onCreate({ editor }) {
  16. _this.updatedAt = Date.now()
  17. },
  18. onUpdate({ editor }) {
  19. _this.updatedAt = Date.now()
  20. },
  21. onSelectionUpdate({ editor }) {
  22. _this.updatedAt = Date.now()
  23. },
  24. })
  25. },
  26. isLoaded() {
  27. return editor
  28. },
  29. isActive(type, opts = {}) {
  30. return editor.isActive(type, opts)
  31. },
  32. toggleHeading(opts) {
  33. editor.chain().toggleHeading(opts).focus().run()
  34. },
  35. toggleBold() {
  36. editor.chain().focus().toggleBold().run()
  37. },
  38. toggleItalic() {
  39. editor.chain().toggleItalic().focus().run()
  40. },
  41. }
  42. })
  43. })
  44. window.Alpine = Alpine
  45. Alpine.start()

将其添加到你的应用

现在,替换 index.html 文件的内容,并使用编辑器组件:

  1. <!doctype html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. </head>
  6. <body>
  7. <div x-data="editor('<p>Hello world! :-)</p>')">
  8. <template x-if="isLoaded()">
  9. <div class="menu">
  10. <button
  11. @click="toggleHeading({ level: 1 })"
  12. :class="{ 'is-active': isActive('heading', { level: 1 }, updatedAt) }"
  13. >
  14. H1
  15. </button>
  16. <button @click="toggleBold()" :class="{ 'is-active' : isActive('bold', updatedAt) }">
  17. Bold
  18. </button>
  19. <button @click="toggleItalic()" :class="{ 'is-active' : isActive('italic', updatedAt) }">
  20. Italic
  21. </button>
  22. </div>
  23. </template>
  24. <div x-ref="element"></div>
  25. </div>
  26. <script type="module" src="/main.js"></script>
  27. <style>
  28. body {
  29. margin: 2rem;
  30. font-family: sans-serif;
  31. }
  32. button.is-active {
  33. background: black;
  34. color: white;
  35. }
  36. .tiptap {
  37. padding: 0.5rem 1rem;
  38. margin: 1rem 0;
  39. border: 1px solid #ccc;
  40. }
  41. </style>
  42. </body>
  43. </html>

Tiptap 现在应该可以在浏览器中看到啦。给自己点个赞吧!:)