0.0.27 • Published 3 months ago

daisy-tiptap-test v0.0.27

Weekly downloads
-
License
-
Repository
-
Last release
3 months ago

DaisyUI Tiptap Editor

基于 Vue3 、 TiptapDaisyUI 的 「所见即所得」 富文本编辑器。易上手,可扩展性强。

Ps: 在这里强调一下。这个不是我自己做的,是拿 Element-Tiptap 魔改的。咱可以点去它那膜拜膜拜大佬,谢谢。

🤡 改动的点

  1. 菜单图标使用的是 Google Fonts 的图标。
  2. DaisyUI 重写了UI,弃用了 Element-Plus 。不是说 Element-Plus 不好用,只是我当前项目没有用这个组件库,所以就单纯只是因为这个去掉了它。
  3. 如果给 link 插件开了 linkOnPaste 功能,剪切板有URL链接文本时,在编辑器中选中文本,然后粘贴,是默认给文本添加超链接,但是在 行内代码代码块 里,这个功能是不可用的,而且它也不会把链接替换掉选中的文本,我理解为是个bug吧(Tiptap官方案例的bug),给改了,在 行内代码代码块 里是默认行为,也就是替换文本。
  4. 原作者的图片插入功能,是默认图片宽度200px的,我觉得有点不合理。我改成,如果图片原宽度大于编辑器宽度,则图片宽度设置为编辑器宽度。反之则是图片原宽度。
  5. 代码块 CodeBlock 默认内置了代码高亮,用的是 highlight.js 插件。没设置主题,需要手动导入对应的css文件。路径为: highlight.js/styles/${你要的主题}.css。如说我现在用的是 gradient-dark.min.css。然后在 CodeBlock 插件的配置中,添加一个 theme 属性,值为 gradient-dark-min,注意是 -min 而不是 .min。具体的主题样式可以在highlight.js Demo 中查看。 6.
  6. 代码块 CodeBlock 默认的语言是 plaintext(可以在配置 defaultLanguage 中改),也就是直接按菜单栏的代码块按钮,添加的是 plaintext 语言的代码块。 为啥提到这一点呢,是因为代码高亮是根据你的语言来区分内容的。 那么如何设置指定语言的代码块呢。就只能用 Markdown 的语法了。比如说我想用 javascript 的代码块,我需要在 空行 中先输入三个 ` 然后跟上语言,再敲回车,就会自动创建指定语言的代码块。
  7. 字体 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 />

readOnlytrue, 编辑器不可编辑。

检查拼写 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>

🏗 致谢

📝 更新日志

日志

📄 许可证

MIT

0.0.27

3 months ago

0.0.25

3 months ago

0.0.26

3 months ago

0.0.20

4 months ago

0.0.21

4 months ago

0.0.22

4 months ago

0.0.23

4 months ago

0.0.24

4 months ago

0.0.19

4 months ago

0.0.10

4 months ago

0.0.11

4 months ago

0.0.12

4 months ago

0.0.13

4 months ago

0.0.14

4 months ago

0.0.15

4 months ago

0.0.9

4 months ago

0.0.16

4 months ago

0.0.8

4 months ago

0.0.17

4 months ago

0.0.18

4 months ago

0.0.5

4 months ago

0.0.4

4 months ago

0.0.7

4 months ago

0.0.6

4 months ago

0.0.3

4 months ago

0.0.2

4 months ago

0.0.1

4 months ago