news 2026/7/1 5:33:26

Vue3 + wangeditor 5.x 保姆级教程:从封装组件到图片视频上传(附完整代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue3 + wangeditor 5.x 保姆级教程:从封装组件到图片视频上传(附完整代码)

Vue3 + wangeditor 5.x 企业级封装实战:打造高可用的富文本上传组件

在后台管理系统开发中,富文本编辑器几乎是标配功能。但市面上大多数教程只停留在基础API调用层面,对于实际企业开发中遇到的样式污染、上传接口对接、组件销毁等痛点问题往往避而不谈。本文将基于Vue3的组合式API,带你从零封装一个生产环境可用的wangeditor组件,重点解决以下问题:

  1. 如何实现图片/视频的自定义上传逻辑
  2. 组件样式隔离的最佳实践方案
  3. 内存泄漏防范与编辑器实例销毁
  4. 支持双向绑定的v-model集成
  5. 上传进度反馈与错误处理机制

1. 环境准备与基础集成

1.1 初始化项目与安装依赖

首先确保你的项目已经配置好Vue3环境。推荐使用Vite作为构建工具:

npm create vite@latest vue3-editor-demo --template vue-ts

安装wangeditor相关依赖:

npm install @wangeditor/editor @wangeditor/editor-for-vue

1.2 基础组件结构

创建src/components/RichEditor.vue文件,搭建基础骨架:

<template> <div class="editor-container"> <Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" mode="default" /> <Editor v-model="modelValue" :defaultConfig="editorConfig" mode="default" @onCreated="handleCreated" /> </div> </template> <script setup lang="ts"> import '@wangeditor/editor/dist/css/style.css' import { onBeforeUnmount, shallowRef } from 'vue' import { Editor, Toolbar } from '@wangeditor/editor-for-vue' const editorRef = shallowRef() const modelValue = defineModel<string>({ required: true }) const handleCreated = (editor: any) => { editorRef.value = editor } </script>

关键点说明:使用shallowRef存储编辑器实例可以避免不必要的响应式开销,这对富文本这种复杂对象尤为重要。

2. 深度配置编辑器功能

2.1 工具栏定制化

wangeditor支持高度自定义的工具栏配置。以下是企业应用中常见的配置方案:

const toolbarConfig = { excludeKeys: [ 'group-video', // 初始隐藏视频功能 'fullScreen', 'insertLink', 'codeBlock' ], insertKeys: { index: 5, keys: ['uploadImage', 'uploadVideo'] } }

2.2 编辑器核心配置

针对不同场景,我们需要灵活调整编辑器的行为:

const editorConfig = { placeholder: '请输入内容...', autoFocus: false, scroll: true, maxLength: 50000, MENU_CONF: {} }

3. 实现文件上传功能

3.1 图片上传方案

企业级应用通常需要对接自己的文件服务,下面是一个完整的图片上传实现:

editorConfig.MENU_CONF['uploadImage'] = { fieldName: 'file', server: '/api/upload/image', maxFileSize: 5 * 1024 * 1024, // 5MB allowedFileTypes: ['image/*'], customUpload: async (file: File, insertFn: Function) => { try { const formData = new FormData() formData.append('file', file) const { data } = await axios.post('/api/upload', formData, { headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: (progressEvent) => { const percent = Math.round( (progressEvent.loaded * 100) / progressEvent.total ) // 可以在这里添加进度显示逻辑 } }) insertFn(data.url, '', '') } catch (error) { console.error('上传失败:', error) // 添加错误提示逻辑 } } }

3.2 视频上传的特殊处理

视频上传需要额外考虑封面和预览问题:

editorConfig.MENU_CONF['uploadVideo'] = { customUpload: async (file: File, insertFn: Function) => { // 先上传视频文件 const videoRes = await uploadFile(file) // 生成视频封面缩略图 const poster = await generateVideoPoster(videoRes.url) insertFn(videoRes.url, poster) } }

4. 生产环境优化策略

4.1 样式隔离方案

避免编辑器样式影响全局样式:

.editor-container { :deep(.w-e-bar) { background-color: #f8f8f8; border: 1px solid #ddd; } :deep(.w-e-text-container) { border: 1px solid #ddd !important; border-top: none !important; } }

4.2 内存管理与性能优化

正确处理组件销毁:

onBeforeUnmount(() => { const editor = editorRef.value if (!editor) return editor.destroy() editorRef.value = null })

4.3 扩展功能集成

实现字数统计功能示例:

const handleChange = (editor: IDomEditor) => { const text = editor.getText() const html = editor.getHtml() // 触发字数变化事件 emit('count-change', { textLength: text.length, htmlLength: html?.length || 0 }) }

5. 完整组件代码与使用示例

5.1 最终组件实现

<template> <div class="rich-editor"> <Toolbar :editor="editorRef" :defaultConfig="toolbarConfig" /> <Editor v-model="modelValue" :defaultConfig="editorConfig" @onCreated="handleCreated" @onChange="handleChange" /> <div v-if="showCount" class="editor-count"> 字数: {{ count }} / {{ maxLength }} </div> </div> </template> <script setup lang="ts"> // 完整导入和配置见上文实现 </script> <style scoped lang="scss"> // 完整样式见上文实现 </style>

5.2 在父组件中使用

<template> <RichEditor v-model="content" :maxLength="10000" @count-change="handleCountChange" /> </template> <script setup> const content = ref('<p>初始内容</p>') const handleCountChange = ({ textLength }) => { console.log('当前字数:', textLength) } </script>

在实际项目中,这个组件已经处理了文件上传、样式隔离、内存管理等企业级关注点,可以直接集成到你的后台系统中。根据具体需求,你还可以进一步扩展如粘贴图片自动上传、自定义表情面板等功能。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 5:32:39

别再手动拼管道了!用3DMax的TycoonBuilder插件,5分钟搞定复杂弯曲模型

3DMax效率革命&#xff1a;TycoonBuilder插件重塑复杂模型创作流程在3D建模领域&#xff0c;时间就是金钱。每当面对需要创建复杂弯曲结构的项目——无论是工业厂房的管道系统、科幻场景中的电缆网络&#xff0c;还是主题公园的过山车轨道——传统的手动拼接方法总会让设计师陷…

作者头像 李华
网站建设 2026/7/1 5:32:04

SQL 避坑指南 - Oracle GROUP BY 整型常量的「薛定谔行为」

最近 PawSQL 的 SQL 解析器撞上了一个诡异的异常情况。下面这条 SQL&#xff0c;在 Oracle 客户端里跑得好好的&#xff0c;PawSQL 却在解析时直接报了个数组越界&#xff1a;SELECT category, count(1) FROM products GROUP BY CATEGORY UNION ALL SELECT 23 as category, 1…

作者头像 李华
网站建设 2026/7/1 5:32:02

DeepSeek推理再提速80%,V4正式版定档7月中旬

DeepSeek两天前开源了DSpark推理加速框架&#xff0c;梁文锋署名。DSpark已经在V4预览版的在线服务上跑了真实流量&#xff0c;把每个用户感受到的生成速度拉高了60%到85%。DSpark用半自回归结构和置信度调度两套机制&#xff0c;化解了推测解码长久以来的尾部衰减与算力浪费问…

作者头像 李华
网站建设 2026/7/1 5:31:30

MySQL增删改实战:从基础语法到企业级安全高效操作指南

你有没有遇到过这样的场景&#xff1a;刚接手一个项目&#xff0c;数据库里空空如也&#xff0c;业务急着要数据&#xff1b;或者线上某个字段填错了&#xff0c;需要批量更新几千条记录&#xff1b;又或者要清理一批过期数据&#xff0c;结果手一抖差点删了不该删的。这些看似…

作者头像 李华
网站建设 2026/7/1 5:30:49

3DSOURCE零件库客户端全新上线工具库频道,机械设计效率翻倍!

各位机械设计师朋友们&#xff0c;好消息来啦&#xff01;3DSOURCE零件库PC客户端更新啦&#xff01;本次更新可谓是干货满满&#xff0c;我们特意为广大机械设计师用户精心打造了工具库频道&#xff0c;内含各类机械设计工程师日常工作中高频使用的计算小工具&#xff0c;助你…

作者头像 李华
网站建设 2026/7/1 5:26:47

使用上下文感知掩码的快速高效声纹识别网络cam++

目录 一、论文基础信息 二、研究背景与现存模型痛点 三、CAM 整体架构设计 四、实验设置 五、实验结果与分析 六、论文四大核心创新点 七、CAM 为什么现在这么流行&#xff1f; 八、全文结论 九、代码测试 一、论文基础信息 论文标题&#xff1a;CAM: A Fast and Eff…

作者头像 李华