tiptap编辑器提供了大量命令Commands,可以添加或更改内容、更改选择。如果你想用好tiptap编辑器,你需要掌握这些命令。
Execute a command
, tiptap 所有可用的命令都通过编辑器实例访问,比如将选中文本加粗的命令如下。
editor.commands.setBold();
Chain commands
大多数的命令可以组合到一个调用中,这比单独的函数调用要短和优雅一些,链命令以.chain()
开头.run()
结尾,将多个命令合并成一个事务,内容只更新一次事件也只触发一次,下面是链命令的代码例子。
editor
.chain()
.focus()
.toggleBold()
.run()
链接命令时,事务被保留,如果要在自定义链命令,则需要使用事务并添加到其中,vue3 例子如下:
<template>
<div class="editor">
<editor-content :editor="state.editor" />
</div>
</template>
<script setup lang="ts">
/*
tiptap 中文文档
https://www.itxst.com/tiptap/tutorial.html
*/
import { getCurrentInstance, onMounted, reactive, ref } from "vue";
import { Editor, EditorContent } from "@tiptap/vue-3";
import StarterKit from "@tiptap/starter-kit";
import Link from '@tiptap/extension-link';
//重写扩展
const CustomLink= Link.extend({
addCommands() {
return {
customCommand: attributes => ({ chain }) => {
// Doesn’t work:
// return editor.chain() …
// Does work:
return chain()
.insertContent('foo!')
.insertContent('bar!')
.run()
},
}
}
})
const state = reactive({
editor: new Editor({
content: "<p>Tiptap 中文文档,回车输入数字看看效果</p>",
extensions: [
StarterKit,
CustomLink
],
}) as any,
});
onMounted(() => {
setTimeout(()=>{
//执行自定义链命令
state.editor.chain().customCommand().run();
},2000)
});
</script>
<style scoped>
.editor {
margin: 10px 20px;
width: 390px;
}
.editor:deep(.ProseMirror) {
color: red;
border: solid 1px #ddd;
padding: 0px 6px;
min-height: 160px;
}
.tools {
display: flex;
background-color: #eee;
padding: 6px;
justify-items: center;
}
.tools > label {
color: #1512e6;
cursor: pointer;
}
.tools > label + label {
margin-left: 10px;
}
.editor:deep(a){
color: #1512e6;
cursor: pointer;
text-decoration: underline;
}
</style>
我们可以在一条链命令中插入业务逻辑,它可以和这个链命令在一个事务中执行(触发一次内容更新、触发一次事件),例子如下:
// 内联命令
editor
.chain()
.focus()
.command(({ tr }) => {
// 在事务中执行以下代码
tr.insertText('hey, that’s cool!')
return true
})
.run()
有时您不想实际执行命令,只想知道是否可以执行命令,比如你执行editor.can().insertContent 它并不会插入内容到编辑器,它只会返回true或者false告诉你能否插入内容。
// 检测 insertContent 命令是否能执行
let res = editor.can().insertContent();
// 检测这条链命令是否能执行
let res = editor
.can()
.chain()
.toggleBold()
.toggleItalic()
.run()
如何你是自己实现一个扩展,希望命令支持试运行,代码如下:.can().insertText()
export default (value) => ({ tr, dispatch }) => {
if (dispatch) {
tr.insertText(value)
}
return true
}
/*
如果无法理解,访问下面连接查看table扩展的实现代码
https://github.com/ueberdosis/tiptap/blob/998e6bbe79208e5ac7fea4f2161102f6c3f9af71/packages/extension-table/src/table.ts
*/
如果你是封装 tiptap 命令,则无需检查,tiptap 会为您完成
addCommands() {
return {
bold: () => ({ commands }) => {
return commands.toggleMark('bold')
},
}
}
如果你只是包装一个普通的 ProseMirror 命令
import { exitCode } from '@tiptap/pm/commands'
export default () => ({ state, dispatch }) => {
return exitCode(state, dispatch)
}
执行第一个命令,如果第一个命令执行成功,那么不会往下执行命令列队,如果第一个命令执行失败,它将会一个一个的命令往下执行
editor.first(({ commands }) => [
() => commands.undoInputRule(),
() => commands.deleteSelection(),
// …
])
也可以在命令中应用commands.first方法
export default () => ({ commands }) => {
return commands.first([
() => commands.undoInputRule(),
() => commands.deleteSelection(),
// …
])
}