当前位置: 首页 > news >正文

Vue3 集成wangEditor 5

1. 依赖

pnpm install @wangeditor/editor --save
pnpm install @wangeditor/editor-for-vue@next --save

2. 在template使用wangEditor 5

  • v-model数据库中查询出来的editor中的数据,数据库中使用longtext类型
 <Toolbar
   style="border-bottom: 1px solid #ccc"
   :editor="editorRef"
   :mode="mode"
 />
 <Editor
   style="height: 500px; overflow-y: hidden;"
   v-model="content" 
   :mode="mode"
   :defaultConfig="editorConfig"
   @onCreated="handleCreated"
 />

3. js代码

  • customInsert:这个配置的作用,发送图片到接口返回的只有图片的文件名,但是要在editor中显示图片需要图片完整的url,这里就是把url补完整
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import {onBeforeUnmount, reactive, shallowRef} from "vue";
import {Editor, Toolbar} from '@wangeditor/editor-for-vue'
/* wangEditor5 初始化开始 */
const editorRef = shallowRef()  // 编辑器实例,必须用 shallowRef
const mode = 'default'
const editorConfig = {MENU_CONF: {}}
// 图片上传配置
editorConfig.MENU_CONF['uploadImage'] = {
  headers: {
    token: '',	
  },
  server: import.meta.env.VITE_BASE_API + "/avatar/wang/upload",  // 服务端图片上传接口
  fieldName: 'file',  // 服务端图片上传接口参数名
  // 后端返回的图片地址不是完整的,可以在这里补全
  customInsert: (res, insertFn) => {
    const baseUrl = import.meta.env.VITE_BASE_API ; // 你要添加的前缀字符串
    const imageUrl = res.data[0].url;
    const newImageUrl = baseUrl + imageUrl;
    insertFn(newImageUrl);
  },
}
// 组件销毁时,也及时销毁编辑器,否则可能会造成内存泄漏
onBeforeUnmount(() => {
  const editor = editorRef.value
  if (editor == null) return
  editor.destroy()
})
// 记录 editor 实例,重要!
const handleCreated = (editor) => {
  editorRef.value = editor
}

4. 后端接口

// 下载
  @RequestMapping("/download/{imgPath}")
  public void download(@PathVariable("imgPath") String fileName, HttpServletResponse response) {
    String UPLOAD_PATH = System.getProperty("user.dir") + "/avatar/" + fileName;
    FileUtilCustom.downloadFile(UPLOAD_PATH, response);
  }
 // wangeditor 指定的上传,返回值比较特殊
  @PostMapping("/wang/upload")
  public Map<String, Object> wangEditorUpload(MultipartFile file) {
    String UPLOAD_PATH = System.getProperty("user.dir") + "/avatar/";
    String fileName = FileUtilCustom.uploadFile(file, UPLOAD_PATH);

    Map<String, Object> resMap = new HashMap<>();
    // wangEditor上传图片成功后, 需要返回的参数
    resMap.put("errno", 0);
    resMap.put("data", CollUtil.newArrayList(Dict.create().set("url", "/avatar/download/" +  fileName)));
    return resMap;
  }

接口中调用的上传和下载的方法

// 自己写的上传和下载,还需要再优化
import cn.hutool.core.io.FileUtil;
import com.example.exception.CustomException;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.multipart.MultipartFile;

import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.UUID;

public class FileUtilCustom {
  /**
   * 文件上传,将文件file放到指定的filePath位置
   * @param file 文件
   * @param filePath 保存文件的绝对路径
   * @return  文件名
   * @throws CustomException 自定义异常,文件上传失败
   */
  public static String uploadFile(MultipartFile file, String filePath) {
    if (file.isEmpty()) {
      return "文件为空";
    }
    if (!FileUtil.isDirectory(filePath)) {
      FileUtil.mkdir(filePath);
    }
    try {
      // 截取UUID的前10位,防止文件名重复
      String fileName = UUID.randomUUID().toString().substring(0,10)+'_' + file.getOriginalFilename();
      FileUtil.writeBytes(file.getBytes(), filePath + fileName);
      return fileName;	// 上传成功后只返回文件名
    }catch (Exception e){
      throw new CustomException("文件上传失败");
    }
  }

  /**
   * 文件下载
   * @param filePath  文件的绝对路径
   * @param response  响应
   * @throws CustomException 自定义异常,文件不存在,文件下载失败
   */
  public static void downloadFile(String filePath, HttpServletResponse response) {
    if (!FileUtil.exist(filePath)) {
      throw new CustomException("文件不存在");
    }
    try {
      String fileName = FileUtil.getName(filePath);
      // 文件名可能包含中文对文件名进行编码
      String encodeName =
        URLEncoder.encode(fileName, StandardCharsets.UTF_8);
      // 设置响应头,需要在跨域设置中,设置"Content-Disposition"
      response.setHeader("Content-Disposition", "attachment'filename=" + encodeName );
      response.setContentType("application/octet-stream");
      OutputStream outputStream = response.getOutputStream();
      FileUtil.writeToStream(filePath, outputStream);
      outputStream.close();
    }catch (Exception e){
      throw new CustomException("文件下载失败");
    }
  }
}

相关文章:

  • 鸿蒙开发真机调试:无线调试和USB调试
  • MQ,RabbitMQ,MQ的好处,RabbitMQ的原理和核心组件,工作模式
  • LeetCode 解题思路 22(Hot 100)
  • 9.嗅探与Wireshark进阶分析
  • 使用Python在Word中创建、读取和删除列表 - 详解
  • DeepSeek接入多模态,个人电脑也能飞速生成高清图,确实可以封神了!
  • 目前主要虚拟世界平台在单一实例承载人数和伺服器架构的综合比较分析(从开资料和技术推估):
  • 寄存器(内部访问)
  • WordPress靶场攻略
  • 微服务》》Kubernetes (K8S) 集群配置网络》》Calico
  • deepseek使用记录24——小灵
  • docker、docker-compose常用命令
  • Java 实现排序算法 TopK 问题
  • AcWing 839:模拟堆 ← multiset + unordered_map
  • 4.玩转热图(续:矩阵式网络关系热图、Pivot Table 热图、三维/交互式热图)——Python数据挖掘代码实践
  • 2025年优化算法:人工旅鼠算法(Artificial lemming algorithm,ALA)
  • Devops之Docker:Docker入门
  • Pandas数据分析
  • 深入解析 Service Worker 在 Chrome 扩展中的应用
  • redis,tar.gz安装后,接入systemctl报错解决
  • 莱布雷希特专栏:古典乐坛边缘人
  • 脱欧后首次英欧峰会召开前夕,双方却因渔业和青年流动议题僵住了
  • 李公明 | 一周画记:德里达哲学还是接地气的
  • 消费维权周报丨上周涉汽车类投诉较多,涉加油“跳枪”等问题
  • 国家统计局:1-4月份,全国固定资产投资同比增长4.0%
  • 高温最强时段来了!北方局地高温有明显极端性