daisy-tiptap-test v0.0.27
DaisyUI Tiptap Editor
基于 Vue3 、 Tiptap 和 DaisyUI 的 「所见即所得」 富文本编辑器。易上手,可扩展性强。
Ps: 在这里强调一下。这个不是我自己做的,是拿 Element-Tiptap 魔改的。咱可以点去它那膜拜膜拜大佬,谢谢。
🤡 改动的点
- 菜单图标使用的是
Google Fonts
的图标。 - 用
DaisyUI
重写了UI,弃用了Element-Plus
。不是说Element-Plus
不好用,只是我当前项目没有用这个组件库,所以就单纯只是因为这个去掉了它。 - 如果给
link
插件开了linkOnPaste
功能,剪切板有URL链接文本时,在编辑器中选中文本,然后粘贴,是默认给文本添加超链接,但是在行内代码
和代码块
里,这个功能是不可用的,而且它也不会把链接替换掉选中的文本,我理解为是个bug吧(Tiptap官方案例的bug),给改了,在行内代码
和代码块
里是默认行为,也就是替换文本。 - 原作者的图片插入功能,是默认图片宽度200px的,我觉得有点不合理。我改成,如果图片原宽度大于编辑器宽度,则图片宽度设置为编辑器宽度。反之则是图片原宽度。
- 代码块
CodeBlock
默认内置了代码高亮,用的是highlight.js
插件。没设置主题,需要手动导入对应的css文件。路径为:highlight.js/styles/${你要的主题}.css
。如说我现在用的是gradient-dark.min.css
。然后在CodeBlock
插件的配置中,添加一个theme
属性,值为gradient-dark-min
,注意是-min
而不是.min
。具体的主题样式可以在highlight.js Demo
中查看。 6. - 代码块
CodeBlock
默认的语言是plaintext
(可以在配置defaultLanguage
中改),也就是直接按菜单栏的代码块按钮,添加的是plaintext
语言的代码块。 为啥提到这一点呢,是因为代码高亮是根据你的语言来区分内容的。 那么如何设置指定语言的代码块呢。就只能用Markdown
的语法了。比如说我想用javascript
的代码块,我需要在空行
中先输入三个 `然后跟上语言,再敲回车,就会自动创建指定语言的代码块。
- 字体
FontFamily
的配置中,有个fontFamilys
属性,传入一个对象,对象的key
是显示在菜单中的字体名称,value
是实际的CSS字体名称。
暂时只想到以上改动,毕竟我是做完了整个项目才来写这个文档的,改了啥已经忘得七七八八了。
💪 TodoList
未来会加入的功能。(多未来我也不清楚。毕竟主业不是程序员,没多少时间玩代码。) *
- 行高
- 插入视频功能
- 浮动菜单功能
🚀 开发时版本
- Vue 3.3.11
- Tiptap 2.1.13
- DaisyUI 4.4.20
🎄 Demo
👉在线试玩
✨ 特色
- 🎨 使用 DaisyUi 组件
- 🔖 支持 markdown 语法 * 📘 TypeScript 支持
- 🌐 目前只支持 i18n(
en
,zh
,zh_tw
),外语咱也不懂,不敢班门弄斧,机翻又怕翻错看不懂,如果有懂的欢迎贡献更多的语言,谢谢。
📦 安装
通过 NPM
yarn add daisy-tiptap
或者
npm install --save daisy-tiptap
安装插件
/* 全局安装 */
// main.ts
import { createApp } from 'vue';
import App from './App.vue';
import DaisyTiptapPlugin from 'daisy-tiptap';
import 'daisy-tiptap/style.css';
const app = createApp(App);
// 安装 daisy-tiptap 插件,现在你已经在全局注册了 `daisy-tiptap` 组件。
app.use(DaisyTiptapPlugin);
app.mount('#app');
-------------------------------------------------------------------------------
/* 局部导入 */
// app.vue
<script setup>
import { DaisyTiptap } from 'daisy-tiptap';
import 'daisy-tiptap/style.css';
</script>
<template>
<DaisyTiptap />
</template>`
🚀 用法
<script setup lang="ts">
import { ref } from 'vue';
import type { Ref } from 'vue';
import type { Editor } from '@tiptap/core';
// 全家桶,根据自己的需要自行导入
import {
DaisyTiptap, // 主组件
Document, // 必须要的插件
Paragraph, // 必须要的插件
Text, // 必须要的插件
// 下面是额外的插件
Blockquote, // 引用
BulletList, // 无序列表(必须要`ListItem`插件)
Bold, // 加粗
Code, // 行内代码
CodeBlock, // 代码块
Color, // 文本颜色
Dropcursor, // 不知道怎么形容,看官方文档吧。https://tiptap.devdocs/editor/api/extensions/dropcursor
Focus, // 大意就是给当前编辑器聚焦的那段落添加你指定className,详情看官方文档吧。https://tiptap.dev/docs/editor/apiextensions/focus
FontFamily, // 字体(必须要`TextStyle`插件)
FontSize, // 字号(必须要`TextStyle`插件)
Gapcursor, // 不知道怎么形容,看官方文档吧。https://tiptapdev/docs/editor/api/extensions/gapcursor
HardBreak, // 不知道怎么形容,看官方文档吧。https://tiptap.devdocs/editor/api/nodes/hard-break
Heading, // 标题
Highlight, // 文本高亮(背景颜色)
History, // 历史记录(也就是撤回和重做)
HorizontalRule, // 分割线
Image, // 图片
Indent, // 缩进
Italic, // 斜体
Link, // 链接
ListItem, // 列表的必要插件(BulletList、OrderedList)
Mention, // `@`插件(找个空白的地方输入`@`你就能理解了。)
OrderedList, // 有序列表
Strike, // 删除线
Subscript, // 下标
Superscript, // 上标
Table, // 表格
TaskList, // 任务列表
TextAlign, // 文本对齐
TextStyle, // 字体、字号的必要插件(FontFamily、FontSize)
Typography, // 一个排版插件,例如说输入--变成——,输入---变成分割线。详情看官方文档吧。https://tiptap.dev/docs/editor/api/extensionstypography
Underline, // 下划线
Emoji // 表情
} from 'daisy-tiptap';
// 中文
import { zh } from 'daisy-tiptap/dist/i18n';
const editorData = ref('<h1>hello world</h1>');
// 菜单的按钮顺序以下列的数组顺序为准。有些是辅助插件,所以并不是每个都有按钮。
const extensions = [
Document,
Paragraph,
Text,
TextStyle,
Heading,
Bold,
Italic,
Underline,
Strike,
FontFamily,
FontSize,
Color,
Highlight,
Subscript,
Superscript,
Blockquote,
Code,
CodeBlock,
BulletList,
OrderedList,
TaskList,
ListItem,
Indent,
TextAlign,
HorizontalRule,
Link,
Image,
Table,
HardBreak,
Emoji,
History,
Dropcursor,
Gapcursor,
Typography,
Focus,
Mention,
]
const editor: Ref<Editor | null> = ref(null)
// 在onCreate才能拿到正常的editor对象。
function handleEditorCreated(e: Editor) {
editor.value = e
// 这里是给`@`插件添加一些提供筛选的名称
e.storage.mention.values.push(...[
'Lea Thompson',
'Cyndi Lauper',
'Tom Cruise',
'Madonna',
'Jerry Hall',
'Joan Collins',
'Winona Ryder',
'Christina Applegate',
'Alyssa Milano',
'Molly Ringwald',
'Ally Sheedy',
'Debbie Harry',
'Olivia Newton-John',
'Elton John',
'Michael J. Fox',
'Axl Rose',
'Emilio Estevez',
'Ralph Macchio',
'Rob Lowe',
'Jennifer Grey',
'Mickey Rourke',
'John Cusack',
'Matthew Broderick',
'Justine Bateman',
'Lisa Bonet'
])
}
</script>
<template>
<DaisyTiptap
v-model="editorData"
:extensions="extensions"
:locale="zh"
placeholder="没有内容的?"
@onCreate="handleEditorCreated"
/>
</template>
📔 Props
扩展 extensions 必需
类型: Array
必需的props,且必需要有 Document
Text
Paragraph
你可以只使用需要的 extension,对应的菜单按钮将会按照你声明的顺序被添加。
所有可用的 extensions: 见上面的用法
可以在 Tiptap 官方找到 extension 的文档。 还可以自定义 extension。查看 Custom extensions了解更多。
占位符 placeholder
类型: string
默认值: ''
当编辑器没有内容的时候,将会显示 placeholder。
<DaisyTiptap placeholder="Write something …" />
内容 content
类型: string
默认值: ''
编辑器的内容,支持双向绑定,双向绑定就是 v-model:content="content"
<DaisyTiptap :content="content" />
或者
<DaisyTiptap v-model:content="content" />
输出 output
类型: string
默认值: html
可选: html
或者 json
<DaisyTiptap output="json" />
只读模式 readOnly
类型: boolean
默认值: false
<DaisyTiptap readonly />
当 readOnly
为 true
, 编辑器不可编辑。
检查拼写 spellCheck
类型: boolean
默认值: false
<DaisyTiptap spellcheck />
编辑器内容是否开启拼写检查。
width, height
类型: string | number
编辑器默认是撑满父元素的。
带单位的字符串值,无单位的值会将 px
作为单位:
<DaisyTiptap :width="700" height="100%" />
上例会被转换为:
width: 700px;
height: 100%;
字数统计 enableCharCount
类型: boolean
默认值: true
是否显示字数统计
字数限制 charCountMax
类型: number
字数限制。
tooltip
类型: boolean
默认值: true
鼠标移到按钮上时是否显示tooltip。
tooltipPosition
类型: string
默认值: top
可选: top
bottom
left
right
显示tooltip的位置
showFloatingMenu
类型: boolean
默认值: false
是否显示浮动菜单。还没做好,所以即便是 true
它也不显示,只是留个坑后面补而已。
locale
指定编辑器国际化语言
<script setup>
import { DaisyTiptap } from 'daisy-tiptap';
import { zh } from 'daisy-tiptap/dist/i18n';
</script>
<template>
<DaisyTiptap :locale="zh" />
</template>
可用的语言:
en
(默认)zh
zh_tw
因为在原作者的项目我改动了一部分内容,导致那部分没有翻译,未避免出现不必要的争执,我直接去掉了,如果有乐意贡献的欢迎 issus
我,谢谢。
👽 事件 Events
- onBeforeCreate: ({ editor }) 在创建视图之前。
- onCreate: ({ editor }) 编辑器已准备就绪。
- onUpdate: ({ output,editor }) 内容已更改。
- onSelectionUpdate: ({ editor }) 选择已更改。
- onTransaction: ({ editor }) 编辑器状态已更改。
- onFocus: ({ editor }) 编辑器聚焦时。
- onBlur: ({ editor }) 编辑器失焦时。
- onDestroy: () 编辑器销毁时。
Example
<script setup>
...some code...
const editorObject = ref()
function onCreate ({ editor }) {
// onCreate 事件里可以拿到已经创建完成的editor对象。
editorObject.value = editor
}
...some code...
</script>
<template>
<DaisyTiptap @onCreate="onCreate" />
</template>
🏗 致谢
- Element-Tiptap
- Tiptap
- DaisyUI
- Vue
- 未能举例完整,请见谅。
📝 更新日志
📄 许可证
3 months ago
3 months ago
3 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago