tiptap 一款支持vue2和vue3、react的网页编辑器,特点是可以非常方便的自定义工具栏和支持html和json格式,你完全可以把编辑器UI设计成你需要的界面,给我个人的感觉tiptap是介于markdown与html之间的一种编辑器很灵活。
无工具栏 轻量化默认不自带工具栏,可扩展性强和简洁
协同 支持html和json,json格式你可以在其他端(安卓、IOS等)实现编辑和浏览
extension 开箱即用的 extension 扩展插件,比如文字颜色扩展、表格扩展
// vue2 安装
npm install @tiptap/vue-2 @tiptap/pm @tiptap/starter-kit
// vue3 安装
npm install @tiptap/vue-3 @tiptap/pm @tiptap/starter-kit
// react 安装
npm install @tiptap/react @tiptap/pm @tiptap/starter-kit
// nuxt.js 安装
npm install @tiptap/vue-2 @tiptap/pm @tiptap/starter-kit
// 导入对于的库及扩展
import { Editor } from '@tiptap/core'
import Document from '@tiptap/extension-document'
import Paragraph from '@tiptap/extension-paragraph'
import Text from '@tiptap/extension-text'
// new 一个编辑器对象
new Editor({
//使用扩展
extensions: [
Document,
Paragraph,
Text,
],
content: '<p>编辑器内容</p>',
// 编辑器自动获取焦点
autofocus: true,
// 编辑器是否可用
editable: true,
injectCSS: false,
})
// 例如安装color扩展(设置文字颜色的扩展)
npm install @tiptap/extension-text-style @tiptap/extension-color
new Editor({
content: "<p>Tiptap 中文文档</p>",
extensions: [
StarterKit,
//配置扩展
Color.configure({
types: ['textStyle'],
})
],
})
//html中 在工具栏使用使用选择颜色html控件,并把选中的颜色赋值给文字
<input type="color" @input="onColor" :value="state.editor.getAttributes('textStyle').color"/>
//js中 导入扩展
import Color from "@tiptap/extension-color";
import TextStyle from "@tiptap/extension-text-style";
//js事件中 设置文字颜色
state.editor.chain().focus().setColor($event.target.value).run();
//如果不能完全看明白,请查看阅读下面vue3的例子,里面包含了扩展的使用方法
<template>
<div>
<div>
<input
type="color"
@input="onColor"
:value="state.editor.getAttributes('textStyle').color"
/>
<label @click="getHTML">获取Html</label>
<label @click="getJSON">获取Json</label>
<label @click="setHTML">设置Html</label>
<label @click="setJSON">设置Json</label>
<label>插入内容</label>
</div>
<editor-content :editor="state.editor" />
<div>
<code>
{{ state.result }}
</code>
</div>
</div>
</template>
<script setup>
/*
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 Color from "@tiptap/extension-color";
import TextStyle from "@tiptap/extension-text-style";
const state = reactive({
editor: new Editor({
content: "<p>Tiptap 中文文档</p>",
extensions: [
StarterKit,
TextStyle,
Color.configure({
types: ["textStyle"],
}),
],
autofocus: true,
editable: true,
injectCSS: false,
}) as any,
result: "",
});
onMounted(() => {
setTimeout(() => {
state.editor.commands.setContent(
"<p>Tiptap 中文文档 <br> https://www.itxst.com</p>",
false
);
//console.log(state.editor.getJSON());
}, 3000);
});
//设置颜色
const onColor = ($event: any) => {
// debugger;
state.editor.chain().focus().setColor($event.target.value).run();
};
//获取Html
const getHTML = () => {
state.result = state.editor.getHTML();
};
//获取Json
const setHTML = () => {
state.editor.commands.setContent("<p> new 新的内容 </p>", false);
};
//设置Html
const getJSON = () => {
state.result = JSON.stringify(state.editor.getJSON());
};
//设置Json
const setJSON = () => {
let doc = {
type: "doc",
content: [
{ type: "paragraph", content: [{ type: "text", text: "Tiptap JSON" }] },
],
};
state.editor.commands.setContent(doc, false);
};
</script>
<style scoped>
.editor {
margin: 10px 20px;
width: 390px;
}
.editor:deep(.ProseMirror) {
color: red;
border: solid 1px #ddd;
padding: 0px 6px;
}
.tools {
display: flex;
background-color: #eee;
padding: 6px;
justify-items: center;
}
.tools > label {
color: #1512e6;
cursor: pointer;
}
.tools > label + label {
margin-left: 10px;
}
</style>