vue+ts+TinyEditor 是基于 Quill 2.0 开发的富文本编辑器,提供丰富的扩展功能,适用于现代 Web 开发的完整安装使用教程

简介

TinyEditor 是基于 Quill 2.0 开发的富文本编辑器,提供丰富的扩展功能,适用于现代 Web 开发。具备模块化设计、轻量级架构和高度可定制化特性,支持多种插件扩展,满足不同场景需求。

核心特性
  • 基于 Quill 2.0 的现代化架构
  • 模块化设计,支持按需加载
  • 提供多种扩展功能(表格、代码高亮、Markdown 支持等)
  • 跨平台兼容性(Web、移动端适配)
  • 支持实时协作编辑

1.安装依赖

复制代码
npm i @opentiny/fluent-editor

npm i dompurify

npm i html2canvas

npm i katex

npm install quill-toolbar-tip

npm install quill-table-up

2.在项目根目录创建 `types/global.d.ts` 类型声明文件

复制代码
//types/global.d.ts
import type Hljs from 'highlight.js'
import type Katex from 'katex'
import type Html2Canvas from 'html2canvas'

//创建类型声明文件,用于声明全局变量的类型
declare global {
    interface Window {
        hljs: typeof Hljs
        katex: typeof Katex
        Html2Canvas: typeof Html2Canvas
    }
}

3.更新 tsconfig.json,确保包含类型声明路径

复制代码
{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "typeRoots": ["./node_modules/@types", "./types"]
  }
}

4.完整代码

复制代码
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import type FluentEditor from '@opentiny/fluent-editor'
import hljs from 'highlight.js'
import Html2Canvas from 'html2canvas'
import katex from 'katex'
import 'highlight.js/styles/atom-one-dark.css'
import 'katex/dist/katex.min.css'

// 安全类型断言挂载
if (import.meta) { // Vite 环境判断
  (window as unknown as { hljs: typeof hljs }).hljs = hljs
  window.katex = katex as unknown as typeof window.katex
  // @ts-ignore
  window.Html2Canvas = Html2Canvas as typeof window.Html2Canvas
}

const editor = ref<FluentEditor>()
const articleRef = ref<HTMLElement>()

interface MentionItem {
  name: string
  age: number
  cn: string
}

const searchKey = 'name'
const mentionList: MentionItem[] = [
  { name: 'Jack', age: 26, cn: 'Jack 杰克' },
  { name: 'Lucy', age: 22, cn: 'Lucy 露西' },
]

const TOOLBAR_CONFIG = [
  ['undo', 'redo', 'clean', 'format-painter'],
  [
    { header: [1, 2, 3, 4, 5, 6, false] },
    { font: [] },
    { size: ['12px', '14px', '16px', '18px', '20px', '24px', '32px', '36px', '48px', '72px'] }
  ],
  ['bold', 'italic', 'strike', 'underline'],
  [{ color: [] }, { background: [] }],
  [{ align: [] }, { list: 'ordered' }, { list: 'bullet' }, { list: 'check' }],
  [{ script: 'sub' }, { script: 'super' }],
  [{ indent: '-1' }, { indent: '+1' }],
  [{ direction: 'rtl' }],
  ['link', 'blockquote', 'code', 'code-block'],
  ['image', 'file'],
  ['emoji', 'video', 'formula', 'screenshot'],
]

const updateHTML = (html: string) => {
  if (articleRef.value) {
    articleRef.value.innerHTML = html
  }
}

onMounted(async () => {
  // 动态导入客户端专用库
  const module = await import('@opentiny/fluent-editor')
  const FluentEditor = module.default

  editor.value = new FluentEditor('#editor-get-content-html', {
    theme: 'snow',
    modules: {
      toolbar: TOOLBAR_CONFIG,
      syntax: { hljs },
      'emoji-toolbar': true,
      file: true,
      mention: {
        itemKey: 'cn',
        searchKey,
        search: (term: string) => {
          return mentionList.filter(item =>
              String(item[searchKey as keyof MentionItem]).includes(term)
          )
        }
      }
    }
  })

  updateHTML(editor.value.root.innerHTML)
  editor.value.on('text-change', () => {
    updateHTML(editor.value?.root.innerHTML || '')
  })
})


</script>

<template>
  <div id="editor-get-content-html">
    <p>Hello <strong>TinyEditor</strong>!</p>
  </div>
  <br>
  预览效果:
  <div
      ref="articleRef"
      class="article ql-editor"
  />
</template>
运行效果
5.国际化

将使用语言通过 options 传入,目前支持语言 zh-CNen-US,默认使用 en-US

Welcome to commit PR for more language support.

可通过函数 changeLanguage({ lang, langText }) 修改当前语言

复制代码
import type { I18N } from '@opentiny/fluent-editor'

 在modules使用
 modules: {
      ...
      i18n: {
        lang: 'zh-CN',
      },
    }

动态变更:

复制代码
function switchLanguage() {
  // 'zh-CN'  'en-US' 
  (editor.getModule('i18n') as I18N).changeLanguage({ lang: 'zh-CN' })
}
总结

TinyEditor 结合 Quill 2.0 的稳定性和扩展性,为开发者提供高效的富文本解决方案。通过灵活的配置和模块化设计,可快速适配不同业务场景。

相关推荐
阳光是sunny10 分钟前
走进AI(1):细说RAG、MCP、Agent、Function Call
前端·ai编程
剪刀石头布啊18 分钟前
var、let、const与闭包、垃圾回收
前端·javascript
剪刀石头布啊20 分钟前
js常见的单例
前端·javascript
剪刀石头布啊21 分钟前
数据口径
前端·后端·程序员
剪刀石头布啊25 分钟前
http状态码大全
前端·后端·程序员
剪刀石头布啊27 分钟前
iframe通信、跨标签通信的常见方案
前端·javascript·html
宇之广曜36 分钟前
搭建 Mock 服务,实现前端自调
前端·mock
yuko093137 分钟前
【手机验证码】+86垂直居中的有趣问题
前端
用户15129054522041 分钟前
Springboot中前端向后端传递数据的几种方式
前端
阿星做前端41 分钟前
如何构建一个自己的 Node.js 模块解析器:node:module 钩子详解
前端·javascript·node.js