vue3 富文本编辑器(建议收藏)

更新时间:

💡一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍 ;
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;

截止目前, 星球 内专栏累计输出 82w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2900+ 小伙伴加入学习 ,欢迎点击围观

在 Web 开发中,富文本编辑器(Rich Text Editor)是用户与内容交互的核心工具。它允许用户通过简单的操作实现文字格式化、插入图片、表格等复杂功能。Vue 3 作为现代前端框架的代表,凭借其响应式系统、组合式 API 和轻量级设计,为构建富文本编辑器提供了理想的开发环境。本文将从基础到进阶,结合实际案例,手把手教你如何在 Vue 3 中实现一个功能丰富的富文本编辑器,并深入解析其核心原理与优化技巧。


二、富文本编辑器的核心概念与实现逻辑

1. 什么是富文本编辑器?

富文本编辑器本质上是一个交互式的文本容器,它通过 JavaScript 操作浏览器的 DOM 元素,将普通的 <textarea> 扩展为支持多格式内容的可视化编辑工具。例如,用户可以通过点击按钮直接设置文字颜色、插入超链接或调整段落对齐方式。

2. Vue 3 如何与富文本编辑器结合?

Vue 3 的响应式系统允许开发者通过数据绑定(Data Binding)和事件监听(Event Handling)与富文本编辑器深度集成。例如,当用户修改文本内容时,Vue 可以实时同步数据到组件的状态(State),并通过生命周期钩子(如 mounted)完成初始化配置。


三、基础实现:从零开始搭建富文本编辑器

1. 选择合适的富文本库

目前主流的富文本库包括 TinymceQuillDraft.js 等。其中 Tinymce 功能全面但体积较大,适合需要复杂功能的场景;而 Quill 以轻量和灵活性著称,适合 Vue 3 的快速开发需求。

示例:使用 Quill 快速搭建基础编辑器

<template>
  <div>
    <div ref="editor" class="editor"></div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import Quill from 'quill';

const editor = ref(null);

onMounted(() => {
  const quill = new Quill(editor.value, {
    theme: 'snow',
    modules: {
      toolbar: [
        ['bold', 'italic', 'underline'],
        [{ header: 1 }, { header: 2 }],
        [{ list: 'ordered' }, { list: 'bullet' }],
      ],
    },
  });
});
</script>

<style>
.editor {
  height: 300px;
  border: 1px solid #ccc;
}
</style>

代码解析

  • 通过 ref 获取 DOM 容器,供 Quill 初始化。
  • onMounted 生命周期钩子确保 DOM 已加载后再执行。
  • modules.toolbar 定义工具栏按钮,支持粗体、斜体、标题等基础功能。

四、进阶功能:扩展编辑器的交互能力

1. 实现图片上传功能

富文本编辑器的实用性往往依赖于扩展功能。例如,用户可能需要通过本地文件或网络链接插入图片。

步骤分解

  1. 监听图片插入事件:通过 Quill 的 addHandler 方法捕获用户触发的插入操作。
  2. 上传图片到服务器:使用 axios 发送文件到后端接口,并返回图片的 URL。
  3. 将图片插入到编辑器:通过 quill.insertEmbed 方法动态添加图片。
<script setup>
import axios from 'axios';

// ... 其他代码 ...

const handleImage = () => {
  const input = document.createElement('input');
  input.setAttribute('type', 'file');
  input.setAttribute('accept', 'image/*');
  input.click();

  input.onchange = async () => {
    const file = input.files[0];
    const formData = new FormData();
    formData.append('image', file);

    try {
      const res = await axios.post('/upload', formData);
      const { url } = res.data;
      const cursor = quill.getSelection().index;
      quill.insertEmbed(cursor, 'image', url);
    } catch (err) {
      console.error('上传失败:', err);
    }
  };
};

// 在工具栏中添加图片按钮
quill.getModule('toolbar').addHandler('image', handleImage);
</script>

比喻解释
这就像给编辑器装上“快递服务”——用户选择图片后,编辑器会像快递员一样,把文件“打包”(FormData)并发送到服务器,再将返回的“收货地址”(图片 URL)贴回编辑器中。


2. 添加代码高亮功能

代码高亮是技术博客或文档编辑的常见需求。通过结合 Prism.js 等库,可以实现语法高亮效果。

实现步骤

  • 在工具栏中添加“代码块”按钮。
  • 当用户选择该按钮时,将当前段落转换为代码块,并应用高亮样式。
<script setup>
import 'prismjs/themes/prism.css';

// ... 其他代码 ...

// 定义代码块类型选项
const codeLanguages = ['javascript', 'python', 'html'];

// 添加代码块按钮
quill.getModule('toolbar').addHandler('code-block', () => {
  const selection = quill.getSelection();
  if (selection) {
    const lang = prompt('请选择语言:', 'javascript');
    if (codeLanguages.includes(lang)) {
      const text = quill.getText(selection.index, selection.length);
      quill.formatText(
        selection.index,
        selection.length,
        'code-block',
        true
      );
      quill.setText(
        selection.index,
        `\n\`\`\`${lang}\n${text}\n\`\`\`\n`,
        'user'
      );
    }
  }
});
</script>

五、优化与注意事项

1. 性能优化

  • 避免频繁操作 DOM:富文本编辑器涉及大量 DOM 操作,可通过 防抖(Debounce)节流(Throttle) 减少渲染频率。
  • 懒加载模块:仅加载用户实际使用的功能模块(如工具栏按钮按需加载)。

2. 安全性与兼容性

  • 内容过滤:使用 DOMPurify 库清理用户输入,防止 XSS 攻击。
  • 跨浏览器测试:确保编辑器在 Chrome、Firefox、Edge 等主流浏览器中表现一致。

六、实际案例:构建一个完整的博客编辑器

1. 功能设计

  • 支持标题、列表、图片插入
  • 代码块高亮
  • 内容实时预览
  • 内容保存与加载

2. 完整代码示例

<template>
  <div class="editor-container">
    <div class="toolbar">
      <!-- 工具栏按钮 -->
    </div>
    <div ref="editor" class="quill-editor"></div>
    <button @click="saveContent">保存内容</button>
    <div v-html="previewContent" class="preview"></div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import Quill from 'quill';
import DOMPurify from 'dompurify';

const editor = ref(null);
const previewContent = ref('');

// 初始化 Quill
onMounted(() => {
  const quill = new Quill(editor.value, {
    // 配置工具栏和主题
  });

  // 监听内容变化,更新预览
  quill.on('text-change', () => {
    previewContent.value = DOMPurify.sanitize(quill.root.innerHTML);
  });
});

// 保存内容到后端
const saveContent = () => {
  const content = quill.root.innerHTML;
  // 发送请求保存内容
};
</script>

七、结论

通过本文的讲解,读者可以掌握 Vue 3 中富文本编辑器的核心实现方法,从基础配置到扩展功能,并了解如何优化性能和保障安全性。富文本编辑器的开发并非一蹴而就,它需要开发者对 DOM 操作、事件处理和第三方库的深度理解。建议读者从简单的功能开始实践,逐步扩展复杂度,最终构建出符合业务需求的工具。

延伸学习

  • 探索 Vue 3 的 Composition API 对富文本编辑器状态管理的优化
  • 研究 Vue 3 + TypeScript 在复杂编辑器中的类型安全实践
  • 探索开源项目(如 Vue-Quill-Editor)的实现原理

掌握这些技能后,你将能够为各类 Web 应用(如博客、文档协作平台、在线表单)提供强大的内容创作支持。

最新发布