Vue中使用vue-quil-editor富文本编辑器+el-upload实现带图片上传到SpringBoot后台接口
场景
系统中经常会用到富文本编辑器,比如新增通知和公告功能,并且需要添加上传图片。
vue-quill-editor官网:
https://www.npmjs.com/package/vue-quill-editor
注:
博客:
https://blog.csdn.net/badao_liumang_qizhi
关注公众号
霸道的程序猿
获取编程相关电子书、教程推送与免费下载。
实现
安装vue-quil-editor
npm install vue-quill-editor --save
引用封装组件
这里没有使用全局引用,要将这个富文本编辑器做成一个组件,方便引用。
所以在项目下的components下新建Editor目录,在此目录下新建index.vue,用来封装并暴露富文本编辑器组件
引入组件需要添加如下代码,包括ccss文件也是必须要引入的
import { quillEditor } from "vue-quill-editor";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
然后在template中添加富文本组件
<quill-editorclass="editor"v-model="content"ref="quillEditor":options="editorOption"@blur="onEditorBlur($event)"@focus="onEditorFocus($event)"@change="onEditorChange($event)"></quill-editor></div>
设置其菜单栏通过
:options="editorOption"
对应的菜单栏的内容定义
editorOption: {placeholder: "",theme: "snow", // or 'bubble'placeholder: "请输入内容",modules: {toolbar: {container: toolbarOptions,handlers: {image: function(value) {if (value) {// 触发input框选择图片文件document.querySelector(".quill-img input").click();} else {this.quill.format("image", false);}}}}}},
注意这里的设置img菜单的点击事件会触发一个function
在方法中根据class属性找到选择器,此选择器是使用的ElementUI的el-upload,会触发其点击事件
el-upload的代码如下
<el-uploadclass="avatar-uploader quill-img":action="uploadImgUrl"name="file":headers="headers":show-file-list="false":on-success="quillImgSuccess":on-error="uploadError":before-upload="quillImgBefore"accept='.jpg,.jpeg,.png,.gif'></el-upload>
使用el-upload进行文件上传到SpringBoot后台并存储到服务器上,以及前端回显照片的路径参照如下博客:
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/107979828
继续看富文本组件,其内容的绑定通过
v-model="content"
来实现,就是组件传递到数据库中存储的内容
存储内容示例:
所以需要提前声明content属性
data() {return {content: this.value,
并且将当前控件的value赋值给content,因为这里是封装的组件,在调用组件时会将数据库中的数据进行回显
<Editor v-model="form.noticeContent" />
然后就能在组件中this.value来获取并赋值给富文本组件绑定的content
为了实现监视这两个的改变而改变,所以添加watch函数
watch: {value: function() {this.content = this.value;}},
然后就是设置其一些事件
@blur="onEditorBlur($event)"@focus="onEditorFocus($event)"@change="onEditorChange($event)"
如果需要对这些事件进行操作可在下面进行重写
onEditorBlur() {//失去焦点事件},onEditorFocus() {//获得焦点事件},onEditorChange() {//内容改变事件this.$emit("input", this.content);},
上面关联了标题栏中的图片的点击事件会执行el-upload的点击事件。
那么在el-upload组件中
:action="uploadImgUrl"
设置其上传的url
:headers="headers"
绑定请求头
headers: {Authorization: 'Bearer ' + getToken()}
请求头里携带token,请求头的设置参考如下
https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108345222
再设置它的一些事件
:on-success="quillImgSuccess":on-error="uploadError":before-upload="quillImgBefore"
对上传前,上传成功和失败的事件进行重写
// 富文本图片上传前quillImgBefore(file) {let fileType = file.type;if(fileType === 'image/jpeg' || fileType === 'image/png'){return true;}else {this.$message.error('请插入图片类型文件(jpg/jpeg/png)');return false;}},quillImgSuccess(res, file) {// res为图片服务器返回的数据// 获取富文本组件实例let quill = this.$refs.quillEditor.quill;// 如果上传成功if (res.code == 200) {// 获取光标所在位置let length = quill.getSelection().index;// 插入图片 res.url为服务器返回的图片地址quill.insertEmbed(length, "image", res.url);// 调整光标到最后quill.setSelection(length + 1);} else {this.$message.error("图片插入失败");}},// 富文本图片上传失败uploadError() {// loading动画消失this.$message.error("图片插入失败");}
注意这里的图片上传成功是事件中,图片上传对应的后台SpringBoot接口
@PostMapping("/common/upload")public AjaxResult uploadFile(MultipartFile file) throws Exception {try {// 上传文件路径String filePath = RuoYiConfig.getUploadPath();// 上传并返回新文件名称String fileName = FileUploadUtils.upload(filePath, file);String url = serverConfig.getUrl() + fileName;AjaxResult ajax = AjaxResult.success();ajax.put("fileName", fileName);ajax.put("url", url);return ajax;} catch (Exception e) {return AjaxResult.error(e.getMessage());}}
在此接口中
String filePath = RuoYiConfig.getUploadPath();
是在application.yml中获取配置的文件上传的路径
然后调用了文件上传工具类的上传方法
String fileName = FileUploadUtils.upload(filePath, file);
最终后台接口返回的url是一个在服务器上绝对路径的图片地址,比如
http://localhost:8080/profile/upload/2020/09/02/e070fd1a26dca6c00acf6db1bc467905.png
然后
// 获取光标所在位置let length = quill.getSelection().index;// 插入图片 res.url为服务器返回的图片地址quill.insertEmbed(length, "image", res.url);// 调整光标到最后quill.setSelection(length + 1);
调用
quill.insertEmbed(length, "image", res.url);
就能实现在富文本中插入照片,插入成功后的富文本编辑器的内容中就会增加
<img src="http://localhost:8080/profile/upload/2020/09/02/e070fd1a26dca6c00acf6db1bc467905.png ">
富文本编辑器封装组件的完整代码
<template><div><!-- 图片上传组件辅助 --><el-uploadclass="avatar-uploader quill-img":action="uploadImgUrl"name="file":headers="headers":show-file-list="false":on-success="quillImgSuccess":on-error="uploadError":before-upload="quillImgBefore"accept='.jpg,.jpeg,.png,.gif'></el-upload><!-- 富文本组件 --><quill-editorclass="editor"v-model="content"ref="quillEditor":options="editorOption"@blur="onEditorBlur($event)"@focus="onEditorFocus($event)"@change="onEditorChange($event)"></quill-editor></div>
</template><script>
import { getToken } from '@/utils/auth'// 工具栏配置
const toolbarOptions = [["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线["blockquote", "code-block"], // 引用 代码块[{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表[{ indent: "-1" }, { indent: "+1" }], // 缩进[{ size: ["small", false, "large", "huge"] }], // 字体大小[{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题[{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色[{ align: [] }], // 对齐方式["clean"], // 清除文本格式["link", "image", "video"] // 链接、图片、视频
];import { quillEditor } from "vue-quill-editor";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";export default {props: {/* 编辑器的内容 */value: {type: String},/* 图片大小 */maxSize: {type: Number,default: 4000 //kb}},components: { quillEditor },data() {return {content: this.value,uploadImgUrl: "",editorOption: {placeholder: "",theme: "snow", // or 'bubble'placeholder: "请输入内容",modules: {toolbar: {container: toolbarOptions,handlers: {image: function(value) {if (value) {// 触发input框选择图片文件document.querySelector(".quill-img input").click();} else {this.quill.format("image", false);}}}}}},uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址headers: {Authorization: 'Bearer ' + getToken()}};},watch: {value: function() {this.content = this.value;}},methods: {onEditorBlur() {//失去焦点事件},onEditorFocus() {//获得焦点事件},onEditorChange() {//内容改变事件this.$emit("input", this.content);},// 富文本图片上传前quillImgBefore(file) {let fileType = file.type;if(fileType === 'image/jpeg' || fileType === 'image/png'){return true;}else {this.$message.error('请插入图片类型文件(jpg/jpeg/png)');return false;}},quillImgSuccess(res, file) {// res为图片服务器返回的数据// 获取富文本组件实例let quill = this.$refs.quillEditor.quill;// 如果上传成功if (res.code == 200) {// 获取光标所在位置let length = quill.getSelection().index;// 插入图片 res.url为服务器返回的图片地址quill.insertEmbed(length, "image", res.url);// 调整光标到最后quill.setSelection(length + 1);} else {this.$message.error("图片插入失败");}},// 富文本图片上传失败uploadError() {// loading动画消失this.$message.error("图片插入失败");}}
};
</script><style>
.editor {line-height: normal !important;height: 192px;
}
.quill-img {display: none;
}
.ql-snow .ql-tooltip[data-mode="link"]::before {content: "请输入链接地址:";
}
.ql-snow .ql-tooltip.ql-editing a.ql-action::after {border-right: 0px;content: "保存";padding-right: 0px;
}.ql-snow .ql-tooltip[data-mode="video"]::before {content: "请输入视频地址:";
}.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {content: "14px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {content: "10px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {content: "18px";
}
.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {content: "32px";
}.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {content: "文本";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {content: "标题1";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {content: "标题2";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {content: "标题3";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {content: "标题4";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {content: "标题5";
}
.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {content: "标题6";
}.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {content: "标准字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {content: "衬线字体";
}
.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {content: "等宽字体";
}
</style>
封装完组件后就是在需要用到的页面进行引用,比如这里是在通知和公告的新增和编辑页面使用。
来到此vue页面,首先在页面中引入该组件
import Editor from '@/components/Editor' ;
然后声明该组件
export default {name: "Notice",components: {Editor},
此页面为发布通知和公告的页面,所以在新增和编辑时的位置添加该组件
<el-col :span="24"><el-form-item label="内容"><Editor v-model="form.noticeContent" /></el-form-item></el-col>
这里的form.noticeContent就是在点击编辑页面时从后台数据库中查询的保存的富文本编辑器的内容。
设计一个公告的数据库,添加存储内容的字段
这样就能实现富文本编辑器的内容的存储和回显以及带照片的上传。
Vue中使用vue-quil-editor富文本编辑器+el-upload实现带图片上传到SpringBoot后台接口相关推荐
- 富文本编辑器CKeditor的配置和图片上传,看完不后悔
CKeditor是一款富文本编辑器,本文将用极为简单的方式介绍一下它的使用和困扰大家很久的图片上传问题,要有耐心. 第一步:如何使用 1.官网下载https://ckeditor.com/ckedit ...
- tiptap - 基于 vue 的优雅流畅的开源富文本编辑器
一款专为 vue.js 打造,设计优雅,体验流畅舒服的现代富文本编辑器. 关于 Tiptap Tiptap 是一款专为 vue 打造的简洁明快的富文本编辑器,通过简单的设置能为用户提供多种优秀的文字编 ...
- 小程序的四次元口袋:editor富文本编辑器的使用、渲染,以及rich-text进行解析
editor富文本 1.介绍 富文本编辑器,可以对图片.文字进行编辑.极大地丰富了我们文章的结构样式,之前小程序还没有自己开发富文本插件,而在2019年微信小程序正式发布了富文本api. 支持的类型 ...
- Vue中使用vue-croper插件实现图片上传裁剪并传到SpringBoot后台接口
场景 前后端分离的项目,前端修改头像时,需要对头像进行裁剪并且能实时预览,然后上传到SpringBoot后台. 实现效果如下 注: 博客: https://blog.csdn.net/badao_li ...
- 小程序editor 富文本编辑器组件
效果: 关于editor 富文本编辑器组件 复制到组件common 里面.json 引用即可 链接:https://pan.baidu.com/s/1_QIp28IOVuyVFfKfFZwxKQ 提取 ...
- froala editor富文本编辑器出现验证失败的解决方法
froala editor富文本编辑器出现验证失败的解决方法 出现这种情况,首先要下载源码包地址 https://www.froala.com/wysiwyg-editor 之后引用本地的 froal ...
- wangEditor - 轻量级web富文本编辑器(可带图片上传)
业务需求: 通过后台编辑文章和图片,上传到前端界面,展示新闻消息模块.这个时候,需要一款简洁的编辑器,百度编辑器是最常用的一种,但是功能太过于复杂,而wangEditor - 轻量级web富文本编辑器 ...
- html 组件化 编辑器,vue.js组件化使用百度富文本编辑器(一)
注意: 本文采用的编辑器为:idea 1.下载百度富文本编辑器,地址:https://ueditor.baidu.com/website/download.html#ueditor 2.加入到stat ...
- uniapp 微信小程序 editor富文本编辑器 api 使用记录
文章目录 1.查看官方示例 2.关于富文本编辑器的工具栏 3.自己实践一下 效果 这里记录一下自己研究学习的结果 之前一直使用textarea 来进行内容的编辑.但是局限性还是太多,最近发现了edit ...
最新文章
- 细数技术指标-[转载]
- 什么是Bi-GRU语义解析
- 解决报错OMP: Error #15: Initializing libiomp5md.dll, but found libiomp5md.dll already initialized.
- 【secureCRT】如何在secureCRT上设置常用的快捷输出按钮栏
- 10倍,BoostKit鲲鹏全局缓存3大创新技术助力Ceph性能提升
- ibm+i+to+mysql_IBM X3650 M3下配置nginx+tomcat+mysql
- vue-cli3的安装使用
- python-gui-pyqt5的使用方法-3--自定义信号的初识
- new mediacontroller(this) this报错_面试官问你JS的this指向,你能跟他聊多少?
- fatal error: hb.h: 没有那个文件或目录
- 【MMD动作+镜头】Bo Peep Bo Peep
- linux下录制视频流,Ubuntu Linux 下的PSP视频输出以及录制
- 屏幕缩放和注释工具(ZoomIt)
- 禁止chrome更新呢
- 什么是 DeFi(去中心化金融)?
- 审慎 合宜与慈善三种学派的分类与核心思想
- 微信公众号用秀米网插入视频
- 【工作记录】网易云信最近联系人中加入本地服务端数据
- 图的遍历 DFS遍历(深学思维)
- hive中文繁简转化opencc4j
热门文章
- mybatis批量更新报错XXXXX-Inline
- Innumerable Ancestors 尺取 dfs序 lca
- Docker安装Logstash7.7.0
- android c 电话联系人,Android 联系人按中文拼音排序
- Java面试宝典系列之基础面试题String、变量、类与对象、集合类、SSH(一)
- MySQL如何存储Emoji表情,UTF-8和UTF-8MB4字符编码有何区别
- mongo 多条件筛选_如何制作提交按钮,实现多条件筛选
- ssh中exit命令退出远程服务器_Linux:ssh远程执行命令并自动退出
- sql 发送邮件网络附件_利用VBA发送附件电子邮件
- beanutils工具类_Apache Commons 工具类介绍及简单使用