接上篇富文本修正器 Tiptap 系列教程——Tiptap 模块&概念详解,本文咱们首要说一下 Tiptap 的常用办法 & 指令。

Tiptap 实例

首要回想一下咱们之前初始化修正器部分:

const editor = new Editor({ ... })

经过new EditoruseEditor初始化得到的editor便是一个修正器实例,实例上存在很多有用办法和特点,下面咱们来一一列举下。

办法

修正器实例供给了很多办法,能够回来任何内容,增加 Tiptap 的可操作性。

can()

检查指令或指令链是否能够履行,不会实际履行。回来值为false/true

比方:之前利用!editor.can().chain().focus().toggleBold().run()来对加粗bold按钮进行启用或禁用。

<button
  @click="editor.chain().focus().toggleBold().run()"
  :disabled="!editor.can().chain().focus().toggleBold().run()"
  :class="{ 'is-active': editor.isActive('bold') }"
>
  bold
</button>

chain()

之前说过,经过chain()能够创立一条链来履行多个办法,终究需求增加.run()来实际履行一切指令。

editor.chain().focus().toggleBold().run()

destroy()

毁掉修正器实例并刊出一切事情,在组件毁掉时调用。

onUnmounted(() => editor.value.destroy())

getHTML()/getJSON()/getText()

获取修正器 HTML/JSON/纯文本 Text 内容。

onUpdate({ editor }) {
  const json = editor.getJSON()
  const html = editor.getHTML()
  // 默许两个节点 nodes 之间两个换行符
  const text = editor.getText()
  // 可传入参数 blockSeparator 操控节点之间的衔接
  const lineText = editor.getText({ blockSeparator: '' })
  console.log(json)
  console.log(html)
  console.log(text)
  console.log(lineText)
}

富文本编辑器Tiptap系列教程——Tiptap常用方法 & 命令详解

getAttributes()

获取当时选中的节点或符号的特点,如获取当时链接的href特点:

editor.getAttributes('link').href

isActive()

回来当时选定的节点或符号是否处于激活状况,如咱们之前用于判别bold是否处于激活状况时,为其增加is-active类:

:class="{ 'is-active': editor.isActive('bold') }"

registerPlugin()/unregisterPlugin()

注册/刊出一个 ProseMirror 插件。

项目中暂时还没有用到,咱们能够看下 vue3 中对BubbleMenu注册插件的代码。

import { BubbleMenuPlugin, BubbleMenuPluginProps } from '@tiptap/extension-bubble-menu'
// ...
onMounted(() => {
  const {
    updateDelay,
    editor,
    pluginKey,
    shouldShow,
    tippyOptions,
  } = props
  editor.registerPlugin(BubbleMenuPlugin({
    updateDelay,
    editor,
    element: root.value as HTMLElement,
    pluginKey,
    shouldShow,
    tippyOptions,
  }))
})
onBeforeUnmount(() => {
  const { pluginKey, editor } = props
  editor.unregisterPlugin(pluginKey)
})
// ...

onMounted中注册插件BubbleMenuPlugin,并在onBeforeUnmount经过pluginKey刊出这个插件。

setOptions()

手动更新修正器的装备。

咱们经过new Editor()初始化时对修正器增加装备之外,还能够经过setOptions()去动态的修正装备,参数同初始化相同。

// 增加 class 款式到修正器实例
editor.setOptions({
  editorProps: {
    attributes: {
      class: 'my-custom-class',
    },
  },
})

setEditable()

更新修正器的可修正状况,承受两个参数editableemitUpdate

// 设置修正器只读
editor.setEditable(false)

特点

目前有 isEditable(是否是修正状况) 和 isEmpty(内容是否为空) 两个特点。

isEditable

回来修正器是可修正的仍是只读的。

editor.isEditable

isEmpty

检查是否有内容。

editor.isEmpty

Commands 指令

Commands 指令用于更改修正器的状况(内容、选区等),仅回来 true/false。Tiptap 修正器供给了大量 Commands 指令,能够增加或更改内容、更改挑选等。只有掌握这些指令,才能更好的运用 Tiptap 修正器。

切记:不要混杂实例办法和 commands 指令,实例办法可回来任何内容,指令仅回来 true/false

履行指令

Tiptap 中一切指令都能够经过修正器实例editor调用,比方在用户单击按钮时将文本设置为粗体:

editor.commands.setBold()

上面指令能够使所选内容变为粗体,但在运用此类指令时是点击外部按钮,会导致修正器失焦,所以通常会经过链式调用使修正器从头获取焦点。

chain 链式调用

大多数的指令能够组合为一个调用,这比独自的函数调用要简略优雅一些,链指令以.chain()最初.run()结尾,将多个指令兼并成一个业务,内容只更新一次(即只触发一次update事情),而且业务也只触发一次,比方修正上面使文本加粗的例子:

editor.chain().focus().toggleBold().run()

上面咱们说过当点击修正器外部区域调用办法时,会导致修正器失焦,所以需求链式调用focus()使修正器从头获取焦点,再继续履行其他办法。

检测指令是否可履行

经过editor.can().xxx()能够判别指令是否能够履行,回来true/false。比方咱们在表格中需求判别当时选中单元格是否能够兼并/拆分,由于并不是所选的单元格就能够进行兼并/拆分操作:

// 是否可兼并
editor.can().mergeCells()
// 是否可拆分
editor.can().splitCell()

Try commands

.first()用于履行指令列表,首要履行第一个指令,假如第一个指令回来true,即履行成功时就会停止;假如第一个指令履行失利,就会接着履行第二个指令,即一个接一个履行,遇到成功履行的指令则停止履行。

如:退格键首要测验撤消输入规则。假如成功,就到此为止。假如没有应用输入规则,因此无法恢复,它将运行下一个指令并删去挑选。

editor.first(({ commands }) => [
  () => commands.undoInputRule(),
  () => commands.deleteSelection(),
  // …
])

也能够在指令中应用 commands.first() 办法

export default () =>
  ({ commands }) => {
    return commands.first([
      () => commands.undoInputRule(),
      () => commands.deleteSelection(),
      // …
    ])
  }

指令合集

Tiptap 有很可运用多指令,包含对文档、节点/符号和选中区域的各种操作,所以要想玩转 Tiptap,必须了解这些指令,知道在什么时候用什么指令。

content 文档指令

  • clearContent

    清空文档中的一切内容。

  • insertContent/insertContentAt

    在当时/指定方位插入纯文本、HTML 或 JSON 节点。这两个指令运用较多,如一些自定义节点插入内容时咱们会运用:

    commands.insertContent({
      type: 'xxx',
      attrs: {},
    })
    

    或许如插入表情内容时:

    props.editor.chain().focus().insertContent(emoji).run()
    
  • setContent

    设置文档内容(用新文档替换该文档),一般用于初始化文档内容。

节点、符号指令

  • clearNodes

    将节点规范化为默许节点,一般用于铲除款式,如:橡皮擦功用。

  • createParagraphNear

    在选中节点后面增加空阶段。

  • deleteNode

    删去选中节点,如一些自定义节点删去时:

    Backspace: () => {
      return this.editor
        .chain()
        .deleteNode(this.name)
        .insertContent('<p></p>')
        .run()
      return false
    }
    
  • extendMarkRange

    扩展当时的挑选以包含当时符号,如将当时选中区域设置为链接:

    props.editor
      .chain()
      .focus()
      .extendMarkRange('link')
      .setLink({ href: link })
      .run()
    
  • setMark

    在当时挑选处增加一个新符号,首要用于对选中文本增加各种符号,如对设置加粗或字体等:

    setFontSize:
      (fontSize) =>
      ({ tr, chain, editor, dispatch }) => {
        return chain().setMark('textStyle', { fontSize }).run()
      },
    unsetFontSize:
      () =>
      ({ chain }) => {
        return chain().setMark('textStyle', { fontSize: null }).run()
      }
    
  • setNode

    将当时节点替换成指定节点,如对当时节点进行标题和正文的切换:

    editor.commands.setNode('paragraph')
    editor.commands.setNode('heading', { level: 1 })
    
  • toggleMark

    在当时挑选处翻开和封闭特定符号,也便是增加或取消增加符号,如:

    editor.commands.toggleMark('bold')
    

    点击一次时选中内容加粗,再次点击选中内容将取消粗体。

  • toggleNode

    类似于 toggleMark,所选节点将在一个节点与另一个节点之间切换,如:

    props.editor.chain().focus().toggleNode('paragraph', 'heading').run()
    

    点击一次时当时节点转为标题,再次点击标题又转为阶段。

  • unsetAllMarks

    将选中内容的一切 marks 符号移除。

  • unsetMark

    与 setMark 效果相反,移除当时选中内容的指定符号。

  • updateAttributes

    更新节点、符号的特点,只需传递需求更改的特点,如针对图片的宽度设置:

    editor.commands.updateAttributes('image', { width: 100 })
    

selection 选区指令

  • blur

    使修正器失去焦点。

  • focus

    将焦点设置回修正器,能够看到上面讲到的大部分链式指令中都用了 focus 指令,而且能够针对光标方位进行设置:

    // 设置修正器获得焦点
    editor.commands.focus()
    // 设置光标坐落修正器开端方位
    editor.commands.focus('start')
    // 设置光标坐落修正器结尾方位
    editor.commands.focus('end')
    // 选中悉数文档
    editor.commands.focus('all')
    // 设置光标到pos=10的方位
    editor.commands.focus(10)
    // 设置光标坐落结尾方位,但是滚动条不滚动到结尾(当内容高度大于修正器高度有滚动条时)
    editor.commands.focus('end', { scrollIntoView: true })
    
  • deleteRange

    删去指定范围内一切内容,如:

    editor.commands.deleteRange({ from: 0, to: 10 })
    
  • deleteSelection

    删去当时选中节点。

  • enter

    触发键盘”Enter”。

  • scrollIntoView

    将视图滚动到当时挑选或光标方位。

  • selectAll

    选中整个文档。

  • setNodeSelection

    给定方位创立一个新的节点选区,如选中图片、列表等块元素,传入节点的所在方位。

  • setTextSelection

    创立一个文本选区,承受 number 或 range,假如传入 range 时会选中文本,传入 number 时仅仅移动光标方位。

    // 仅移动光标
    editor.commands.setTextSelection(6)
    // 选中文本区域
    editor.commands.setTextSelection({ from: 6, to: 8 })
    

总结

本文首要讲了 Tiptap 实例办法和常用指令,记住不要混杂实例办法和指令

咱们只需求记住这些 API 的大约效果,脑袋里有个“影子”。一旦某个当地需求这么做的时候,要能回想起好像已经有办法实现了,然后再去具体查看对应的办法,终究运用它并解决问题,这套思维适用于一切 API 较多的组件、结构等。

这篇文章完后,关于自定义节点、符号扩展等的文章暂时不再更新。leader 组织我做 webrtc 音视频通话的调研作业,等完结这部分作业后继续更新。

以上便是本文的悉数内容,期望这篇文章对你有所帮助,欢迎点赞和保藏 ,假如发现有什么过错或许更好的解决方案及主张,欢迎随时联络。