Vue 集成富文本编辑器教程

​​​一 选型与对比​

  • 常见方案与适用场景如下(按功能完备度与定制性排序):
    • ​Tiptap(Vue 3 推荐)​ :基于 ​ProseMirror​,无头架构、可扩展性强,适合复杂内容与协同编辑。
    • ​CKEditor 5​ :官方提供 ​Vue 组件​,功能全面,适合企业级内容生产。
    • ​TinyMCE​:插件丰富、配置灵活,适合中大型后台系统。
    • ​Quill​:轻量、模块化,生态成熟,适合常规富文本编辑。
    • ​WangEditor​:中文友好、上手快,适合中小型项目快速落地。
    • ​mavonEditor / Vditor​ :偏 ​Markdown​ 场景,支持所见即所得与分屏预览。

​二 快速上手 Quill Vue 3 示例​

  • 安装依赖(Vue 3 + Quill 官方封装):

    • npm 安装:​npm i quill @vueup/vue-quill@next​
  • 组件代码(含双向绑定与工具栏配置):

    html 复制代码
    <template>
      <div class="editor-container">
        <QuillEditor
          v-model:content="content"
          contentType="html"
          :toolbar="toolbar"
          theme="snow"
          @ready="handleReady"
        />
        <button @click="logContent">打印内容</button>
      </div>
    </template>
    
    <script setup>
    import { ref } from 'vue'
    import { QuillEditor } from '@vueup/vue-quill'
    import '@vueup/vue-quill/dist/vue-quill.snow.css'
    
    const content = ref('<p>初始内容</p>')
    
    const toolbar = [
      ['bold', 'italic', 'underline', 'strike'],
      [{ header: [1, 2, 3, false] }],
      [{ list: 'ordered' }, { list: 'bullet' }],
      ['blockquote', 'code-block'],
      ['link', 'image'],
      ['clean']
    ]
    
    const handleReady = (editor) => {
      console.log('Quill 实例:', editor)
    }
    
    const logContent = () => {
      console.log('HTML:', content.value)
    }
    </script>
    
    <style scoped>
    .editor-container {
      max-width: 900px;
      margin: 20px auto;
    }
    </style>
  • 要点:

    • 使用 ​v-model:content​ 绑定 HTML 内容;设置 ​contentType="html"​
    • 引入主题样式 ​@vueup/vue-quill/dist/vue-quill.snow.css​

​三 图片上传与表单提交​

  • 图片上传思路

    • 方案 A(推荐):服务端提供上传接口,前端将图片转为 ​Blob/File​​FormData​ 上传,成功后插入编辑器。
    • 方案 B:使用编辑器扩展(如 Quill 的 ​imageUploader​ )或官方插件(如 CKEditor 的 ​Image​ 扩展)进行上传与回显。
  • 表单提交示例(以 Quill 为例)

    html 复制代码
    <template>
      <form @submit.prevent="handleSubmit">
        <QuillEditor v-model:content="form.content" contentType="html" />
        <button type="submit">提交</button>
      </form>
    </template>
    
    <script setup>
    import { reactive } from 'vue'
    import { QuillEditor } from '@vueup/vue-quill'
    import '@vueup/vue-quill/dist/vue-quill.snow.css'
    
    const form = reactive({ content: '' })
    
    const handleSubmit = async () => {
      // 直接提交 HTML 到后端
      await fetch('/api/articles', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(form)
      })
      // TODO: 处理响应
    }
    </script>
  • 安全与清理建议

    • 服务端对 HTML 做 ​XSS 过滤/白名单​ (如移除 ​script/style/on​* 等危险属性与标签)。
    • 展示端使用 ​v-html​ 时配合内容安全策略(CSP)与可信来源的资源加载。

​四 常见问题与最佳实践​

  • SSR/同构渲染
    • 富文本编辑器多为浏览器 DOM 依赖,建议在 ​客户端挂载后初始化​ (如 ​onMounted​​client-only​ 包裹),避免服务端渲染报错。
  • 销毁与内存泄漏
    • 组件卸载前调用编辑器实例的 ​destroy​ 方法,移除事件监听与定时器。
  • 图片与文件上传
    • 统一走后端接口,返回可公网访问的 ​URL​;限制大小与类型;失败需提示并可重试。
  • 内容长度与性能
    • 限制编辑器最大字符数/图片数量;大数据量时考虑 ​懒加载​、分页或分片保存。
  • 可访问性(a11y)
    • 保留语义标签与快捷键;为工具栏按钮提供 ​aria-label​;支持键盘导航。
  • 移动端体验
    • 选择移动端适配良好的编辑器或启用轻量工具栏;优化虚拟键盘弹出体验。

​五 其他方案快速指引​

  • CKEditor 5(Vue 3)

    • 安装:​npm i @ckeditor/ckeditor5-vue @ckeditor/ckeditor5-build-classic​

    • 使用:

      html 复制代码
      <template>
        <ckeditor :editor="ClassicEditor" v-model="content" />
      </template>
      
      <script setup>
      import CKEditor from '@ckeditor/ckeditor5-vue'
      import ClassicEditor from '@ckeditor/ckeditor5-build-classic'
      import { ref } from 'vue'
      
      const content = ref('<p>Hello CKEditor 5</p>')
      </script>
  • TinyMCE(Vue 3)

    • 安装:​npm i @tinymce/tinymce-vue​

    • 使用:

      html 复制代码
      <template>
        <editor v-model="content" :init="init" />
      </template>
      
      <script setup>
      import { Editor } from '@tinymce/tinymce-vue'
      import { ref } from 'vue'
      
      const content = ref('')
      const init = {
        height: 400,
        menubar: false,
        plugins: 'lists link image table code',
        toolbar: 'undo redo | bold italic | alignleft aligncenter alignright | bullist numlist | link image | code'
      }
      </script>
  • WangEditor(Vue 2/3 均可)

    • 安装:​npm i wangeditor​

    • 使用要点:

      javascript 复制代码
      import E from 'wangeditor'
      // 挂载到 DOM 后 new E(dom).create()
      // 获取/设置:editor.getText() / editor.setHtml(html)
  • Tiptap(Vue 3,无头与协同)

    • 安装:​npm i @tiptap/vue-3 @tiptap/starter-kit​

    • 使用:

      html 复制代码
      <template>
        <editor-content :editor="editor" />
      </template>
      
      <script setup>
      import { useEditor, EditorContent } from '@tiptap/vue-3'
      import StarterKit from '@tiptap/starter-kit'
      
      const editor = useEditor({
        content: '<p>Hello Tiptap</p>',
        extensions: [StarterKit]
      })
      </script>
  • 选型建议

    • 追求可扩展与协同:选 ​Tiptap​
    • 开箱即用与功能完备:选 ​CKEditor 5 / TinyMCE​
    • 中文生态与轻量:选 ​WangEditor​
    • Markdown 为主:选 ​mavonEditor / Vditor​
相关推荐
CaliXz1 小时前
取出51.la统计表格内容为json数据 api
java·javascript·json
开发者小天1 小时前
React中的受控组件示例
前端·javascript·react.js
奋斗吧程序媛1 小时前
request请求相关
前端·javascript·vue.js
dragoooon341 小时前
[Linux网络基础——Lesson9.「TCP 全连接队列与 tcpdump 抓包」]
前端·git·github
光影少年1 小时前
用vite还是webpack多,vite为什么快
前端·webpack·node.js
waeng_luo1 小时前
[鸿蒙2025领航者闯关] 鸿蒙应用中如何管理组件状态?
前端·harmonyos·鸿蒙·鸿蒙2025领航者闯关·鸿蒙6实战·开发者年度总结
克喵的水银蛇1 小时前
Flutter 通用列表项封装实战:适配多场景的 ListItemWidget
前端·javascript·flutter
Howie Zphile1 小时前
做移动端的 Next.js 项目,可以选哪些 UI?
开发语言·javascript·ui
WX-bisheyuange1 小时前
基于Spring Boot的宠物商城网站设计与实现
前端·javascript·vue.js·毕业设计