tiptap编辑器:概览

547 阅读4分钟

1. 特性:

  1. 是一个前端编辑器库
  2. 基于ProseMirror(一个更轻量的编辑器库,tiptap是对它的拓展)开发
  3. 无头:非开箱即用的,只提供各种功能。样式和交互自由度高
  4. 框架无关:只要基于web前端,无论是纯js,react/vue...都可以使用
  5. 扩展性:提供了自定义扩展能力,满足各种个性化需求

2. 安装使用

2.1 基础概念

首先要了解tiptap的项目构成:

  1. @tiptap/pm 对ProseMirror核心模块的封装,如:
    state 状态 | view 视图 | model 模型 | commands 指令 | schema 框架
  2. @tiptap/core 核心库,概念:
    1. Editor 编辑器核心模块
    2. Extensions 扩展模块
    3. Schema 文档结果定义,即哪些节点(Node)和标记(Mark)是允许出现的
    4. Transaction 代表一次变化,基于此实现对文档的交互操作和回退
  3. @tiptap/starter-kit 包含了基础组件模块:
    1. Node:段落:Paragraph | 标题:Heading | 代码块:CodeBlock | 引用块:Blockquote | 无序列表:BulletList | 有序列表:OrderedList | 列表项:ListItem | 分割线:HorizontalRule | 图片:Image
    2. Mark:加粗:Bold | 斜体:Italic | 删除线:Strike | 行内代码:Code | 强制换行:HardBreak | 链接:Link
    3. 其他:撤销和重做:History | 文档根节点:Document

2.2 使用(纯JS环境)

以下是一个最基础的Tiptap使用案例(重点关注🌈):

import { Editor } from '@tiptap/core'          // 1.引入核心Editor模块
import StarterKit from '@tiptap/starter-kit'   // 2. 引入基础组件模块

new Editor({                                   // 4. 🌈创建tiptap Editor实例
  element: document.querySelector('.element'), // 5. element:实例参数,选取挂载节点
  extensions: [StarterKit],                    // 6. 🌈extensitions:加入扩展
  content: '<p>Hello World!</p>',              // 7. 🌈content:插入内容
})

2.2.1 Editor配置项

Editor类还有哪些配置参数呢(重点关注🌈):

import { Editor } from '@tiptap/core'          // 1. 引入核心库
// 这里只是为了告诉你可以引入多个扩展,一般用@tiptap/starter-kit就行了
import Document from '@tiptap/extension-document' // 3. 引入根节点
import Paragraph from '@tiptap/extension-paragraph' // 4. 同上,引入段落
import Text from '@tiptap/extension-text'      // 5. 同上,引入文本

new Editor({ // 7. 开始,创建实例
  element: document.querySelector('.element'), // 8. 选定挂载节点
  extensions: [Document, Paragraph, Text],     // 9. 加入扩展
  content: '<p>Example Text</p>',              // 10. 插入内容
  autofocus: true,                             // 11. 🌈是否自动焦点:'start' | 'end' | 'all' | number | boolean | null
  editable: true,                              // 12. 🌈是否可编辑:boolean
  injectCSS: false,                            // 13. 🌈禁用默认样式
})

2.2.2 配置扩展组件

另外,我们可以对extensions的传入项(Extensions: Node | Mark | Extension)进行自由配置。
比如Headinglevels指定标题有什么等级(type Level = 1 | 2 | 3 | 4 | 5 | 6)
默认值是:[1, 2, 3, 4, 5, 6],如果只想要h1 h2 h3(重点关注🌈):

import { Editor } from '@tiptap/core' // 1. 引入核心库
// ... 2. 引入其他组件
import Heading from '@tiptap/extension-heading' // 3. 引入Heading

new Editor({
  element: document.querySelector('.element'),
  extensions: [
    // ... 8. 加入其他组件
    Heading.configure({          // 9.  🌈修改默认参数。所有的Node|Mark|Extension都有config和configure
      levels: [1, 2, 3],         // 10. 🌈levels:设置heading允许的level
      HTMLAttributes: {          // 11. 🌈HTMLAttributes:设置组件HTML标签的属性
        class: 'custom-heading'  // 12. 🌈自定义类名
      },
    }),
  ],
})

也可以修改编辑器根节点的属性,顺便看看tiptap Editop的配置结构(重点关注🌈):

new Editor({               // 1. EditorOptions:针对整个Editor对象的配置,用于创建Editor对象
  editorProps: {           // 2. EditorProps:核心配置,用于精细管理editor行为
    attributes: {          // 3. EditorProps.attributes 根节点标签属性
      class: 'my-editor',  // 4. 🌈设置类名
    },
    // 6. 🌈此外,EditorProps 还包含:
    // 7. 基础事件
    // handleKeyDown: ...  // 8.  键盘事件
    // handleClick: ...    // 9.  鼠标事件
    // handleDrop: ...     // 10. 拖拽事件
    // 11. 高级事件
    // handleScrollToSelection: ... // 12. 当视图在更新其状态之后试图将所选内容滚动到视图中时
    // createSelectionBetween: ...  // 13. 文本选取发生改变事触发
    // ...
  },
  // 16. 🌈EditorOptions的属性还包括:
  // 17. 必要属性
  element: document.querySelector('.element'), // 18. Element:挂载元素对象
  extensions: [Document, Paragraph, Text],     // 19. Extensions:拓展组件、节点
  content: '<p>Example Text</p>',              // 20. Content:内容
  // 21. 配置项(常用例举)
  editable: true,                              // 22. 是否允许编辑
  autofocus: true,                             // 23. 自动获取焦点行为
  // 24. 顶层事件(常用例举)
  // onCreate: ...                             // 25. 创建事件
  // onUpdate: ...                             // 26. 内容更新事件
  // onFocus: ...                              // 27. 焦点获取事件
})

总的来说,Tiptap采用的是一个选项式optionality的使用思路,
我们要重点关注这棵"选项树"的关键节点和定义:

mindmap
  Editor编辑器核心
    EditorOptions顶层
      element:Element 挂载元素
      content:Content 内容
      extensions:Extension | Node | Mark 拓展类型
      ...
      editorProps:EditorProps 核心
        handleKeyDown
        handleClick
        handleDrop
        handleScrollToSelection
        createSelectionBetween
        ...

后面的学习就是这棵基础但不完整的树的细节刻画了。

敬请期待。