19. SpringBoot+Vue集成富文本编辑器

1425 字约 3 分钟读完1499 次阅读更新于 2026/5/3

新建一个表 news

CREATE TABLE `news` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '标题',
  `description` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '简介',
  `content` text COLLATE utf8mb4_unicode_ci COMMENT '内容',
  `authorid` int(11) DEFAULT NULL COMMENT '发布人id',
  `time` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '发布时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='新闻信息';

创建 entity 跟表对应

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;

@Data
public class News {
    @TableId(type= IdType.AUTO)
    private Integer id;
    private String title;
    private String description;
    private String content;
    private Integer authorid;
    private String time;

}

创建对应的 Mapper Service Controller

NewsMapper

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.springboot.entity.News;
import com.example.springboot.entity.User;

public interface NewsMapper extends BaseMapper<News> {

}

NewsService

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springboot.entity.News;
import com.example.springboot.mapper.NewsMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service
public class NewsService extends ServiceImpl<NewsMapper, News> {

    @Resource
    NewsMapper newsMapper;

}

NewsController

News.vue

wangeditor

https://www.wangeditor.com/v4/

安装

npm i wangeditor --save

image.png

使用

<div id="editor"></div>


import E from "wangeditor"

export default {
  data() {
    return {
      editor: null
    }
}


this.editor = new E(`#editor`)
// 设置参数
this.editor.create()  // 创建

image.png

销毁编辑器

// 在dialog销毁时调用
closeDialog() {
  // 销毁编辑器
  this.editor.destroy()
  this.editor = null
},

配置代码高亮

npm install highlight.js -S
import hljs from 'highlight.js'

// 在main.js 引入css
import 'highlight.js/styles/monokai-sublime.css'

this.editor.highlight = hljs

设置和获取内容

this.editor.txt.html('')   // 设置html

this.editor.txt.html()   // 获取内容

show-overflow-tooltip 表格处理文本比较多的情形

富文本内容显示

<el-dialog title="内容" :visible.sync="fromVisible1" width="60%">
  <div class="w-e-text">
    <div v-html="content"></div>
  </div>
  <div slot="footer" class="dialog-footer">
    <el-button type="primary" @click="fromVisible1 = false">确 定</el-button>
  </div>
  </el-dialog>

配置图片上传接口

this.editor.config.uploadImgServer = this.$baseUrl + '/file/editor/upload'
this.editor.config.uploadFileName = 'file'
this.editor.config.uploadImgHeaders = {
  token: this.user.token
}

image.png
因为 401 了,后台鉴权不通过

server 接口返回格式,重要!!!

{
  	"errno": 0,
    "data": [
        {
            url: "图片地址"
        }
		]
}

上传的接口

@PostMapping("/editor/upload")
public Dict editorUpload(MultipartFile file) throws IOException {
    String originalFilename = file.getOriginalFilename();  // 文件的原始名称
    // aaa.png
    String mainName = FileUtil.mainName(originalFilename);  // aaa
    String extName = FileUtil.extName(originalFilename);// png
    if (!FileUtil.exist(ROOT_PATH)) {
        FileUtil.mkdir(ROOT_PATH);  // 如果当前文件的父级目录不存在,就创建
    }
    if (FileUtil.exist(ROOT_PATH + File.separator + originalFilename)) {  // 如果当前上传的文件已经存在了,那么这个时候我就要重名一个文件名称
        originalFilename = System.currentTimeMillis() + "_" + mainName + "." + extName;
    }
    File saveFile = new File(ROOT_PATH + File.separator + originalFilename);
    file.transferTo(saveFile);  // 存储文件到本地的磁盘里面去
    String url = "http://" + ip + ":" + port + "/file/download/" + originalFilename;
    if ("img".equals(type)) {  // 上传图片
        return Dict.create().set("errno", 0).set("data", CollUtil.newArrayList(Dict.create().set("url", url)));
    } else if ("video".equals(type)) {
        return Dict.create().set("errno", 0).set("data", Dict.create().set("url", url));
    }
    return Dict.create().set("errno", 0);
}

上传参数

this.editor.config.uploadImgHeaders = {
    token: this.user.token
}

配置视频上传

this.editor.config.uploadVideoServer = this.$baseUrl + '/file/editor/upload'
this.editor.config.uploadVideoName = 'file'
this.editor.config.uploadVideoHeaders = {
  token: this.user.token
}

上传参数

editor.config.uploadVideoHeaders = {
	token: this.user.token
}

完整的富文本前端代码

Vue 完整的封装的富文本的代码

setRichText() {
  this.$nextTick(() => {
    this.editor = new E(`#editor`)
    this.editor.highlight = hljs
    this.editor.config.uploadImgServer = this.$baseUrl + '/file/editor/upload'
    this.editor.config.uploadFileName = 'file'
    this.editor.config.uploadImgHeaders = {
      token: this.user.token
    }
    this.editor.config.uploadImgParams = {
      type: 'img',
    }
    this.editor.config.uploadVideoServer = this.$baseUrl + '/file/editor/upload'
    this.editor.config.uploadVideoName = 'file'
    this.editor.config.uploadVideoHeaders = {
      token: this.user.token
    }
    this.editor.config.uploadVideoParams = {
      type: 'video',
    }
    this.editor.create()  // 创建
  })
},

注意编辑的时候需要延迟加载:

this.setRichText()
  setTimeout(() => {
    this.editor.txt.html(row.content)  // 设置富文本内容
  }, 0)