日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vue中使用vue-quil-editor富文本编辑器+el-upload实现带图片上传到SpringBoot后台接口

發(fā)布時間:2025/3/19 vue 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Vue中使用vue-quil-editor富文本编辑器+el-upload实现带图片上传到SpringBoot后台接口 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

場景

系統(tǒng)中經(jīng)常會用到富文本編輯器,比如新增通知和公告功能,并且需要添加上傳圖片。

?

vue-quill-editor官網(wǎng):

https://www.npmjs.com/package/vue-quill-editor

注:

博客:
https://blog.csdn.net/badao_liumang_qizhi
關(guān)注公眾號
霸道的程序猿
獲取編程相關(guān)電子書、教程推送與免費(fèi)下載。

實(shí)現(xiàn)

安裝vue-quil-editor

npm install vue-quill-editor --save

引用封裝組件

這里沒有使用全局引用,要將這個富文本編輯器做成一個組件,方便引用。

所以在項(xiàng)目下的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>

設(shè)置其菜單欄通過

:options="editorOption"

對應(yīng)的菜單欄的內(nèi)容定義

????? editorOption: {placeholder: "",theme: "snow", // or 'bubble'placeholder: "請輸入內(nèi)容",modules: {toolbar: {container: toolbarOptions,handlers: {image: function(value) {if (value) {// 觸發(fā)input框選擇圖片文件document.querySelector(".quill-img input").click();} else {this.quill.format("image", false);}}}}}},

注意這里的設(shè)置img菜單的點(diǎn)擊事件會觸發(fā)一個function

在方法中根據(jù)class屬性找到選擇器,此選擇器是使用的ElementUI的el-upload,會觸發(fā)其點(diǎn)擊事件

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進(jìn)行文件上傳到SpringBoot后臺并存儲到服務(wù)器上,以及前端回顯照片的路徑參照如下博客:

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/107979828

繼續(xù)看富文本組件,其內(nèi)容的綁定通過

v-model="content"

來實(shí)現(xiàn),就是組件傳遞到數(shù)據(jù)庫中存儲的內(nèi)容

存儲內(nèi)容示例:

?

所以需要提前聲明content屬性

? data() {return {content: this.value,

并且將當(dāng)前控件的value賦值給content,因?yàn)檫@里是封裝的組件,在調(diào)用組件時會將數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行回顯

<Editor v-model="form.noticeContent" />

然后就能在組件中this.value來獲取并賦值給富文本組件綁定的content

為了實(shí)現(xiàn)監(jiān)視這兩個的改變而改變,所以添加watch函數(shù)

? watch: {value: function() {this.content = this.value;}},

然后就是設(shè)置其一些事件

????? @blur="onEditorBlur($event)"@focus="onEditorFocus($event)"@change="onEditorChange($event)"

如果需要對這些事件進(jìn)行操作可在下面進(jìn)行重寫

??? onEditorBlur() {//失去焦點(diǎn)事件},onEditorFocus() {//獲得焦點(diǎn)事件},onEditorChange() {//內(nèi)容改變事件this.$emit("input", this.content);},

上面關(guān)聯(lián)了標(biāo)題欄中的圖片的點(diǎn)擊事件會執(zhí)行el-upload的點(diǎn)擊事件。

那么在el-upload組件中

:action="uploadImgUrl"

設(shè)置其上傳的url

:headers="headers"

綁定請求頭

????? headers: {Authorization: 'Bearer ' + getToken()}

請求頭里攜帶token,請求頭的設(shè)置參考如下

https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/108345222

再設(shè)置它的一些事件

????? :on-success="quillImgSuccess":on-error="uploadError":before-upload="quillImgBefore"

對上傳前,上傳成功和失敗的事件進(jìn)行重寫

??? // 富文本圖片上傳前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為圖片服務(wù)器返回的數(shù)據(jù)// 獲取富文本組件實(shí)例let quill = this.$refs.quillEditor.quill;// 如果上傳成功if (res.code == 200) {// 獲取光標(biāo)所在位置let length = quill.getSelection().index;// 插入圖片? res.url為服務(wù)器返回的圖片地址quill.insertEmbed(length, "image", res.url);// 調(diào)整光標(biāo)到最后quill.setSelection(length + 1);} else {this.$message.error("圖片插入失敗");}},// 富文本圖片上傳失敗uploadError() {// loading動畫消失this.$message.error("圖片插入失敗");}

注意這里的圖片上傳成功是事件中,圖片上傳對應(yīng)的后臺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中獲取配置的文件上傳的路徑

然后調(diào)用了文件上傳工具類的上傳方法

String fileName = FileUploadUtils.upload(filePath, file);

最終后臺接口返回的url是一個在服務(wù)器上絕對路徑的圖片地址,比如

http://localhost:8080/profile/upload/2020/09/02/e070fd1a26dca6c00acf6db1bc467905.png

然后

??????? // 獲取光標(biāo)所在位置let length = quill.getSelection().index;// 插入圖片? res.url為服務(wù)器返回的圖片地址quill.insertEmbed(length, "image", res.url);// 調(diào)整光標(biāo)到最后quill.setSelection(length + 1);

調(diào)用

quill.insertEmbed(length, "image", res.url);

就能實(shí)現(xiàn)在富文本中插入照片,插入成功后的富文本編輯器的內(nèi)容中就會增加

<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" }],??????????? // 縮進(jìn)[{ size: ["small", false, "large", "huge"] }],?? // 字體大小[{ header: [1, 2, 3, 4, 5, 6, false] }],???????? // 標(biāo)題[{ 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: {/* 編輯器的內(nèi)容 */value: {type: String},/* 圖片大小 */maxSize: {type: Number,default: 4000 //kb}},components: { quillEditor },data() {return {content: this.value,uploadImgUrl: "",editorOption: {placeholder: "",theme: "snow", // or 'bubble'placeholder: "請輸入內(nèi)容",modules: {toolbar: {container: toolbarOptions,handlers: {image: function(value) {if (value) {// 觸發(fā)input框選擇圖片文件document.querySelector(".quill-img input").click();} else {this.quill.format("image", false);}}}}}},uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上傳的圖片服務(wù)器地址headers: {Authorization: 'Bearer ' + getToken()}};},watch: {value: function() {this.content = this.value;}},methods: {onEditorBlur() {//失去焦點(diǎn)事件},onEditorFocus() {//獲得焦點(diǎn)事件},onEditorChange() {//內(nèi)容改變事件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為圖片服務(wù)器返回的數(shù)據(jù)// 獲取富文本組件實(shí)例let quill = this.$refs.quillEditor.quill;// 如果上傳成功if (res.code == 200) {// 獲取光標(biāo)所在位置let length = quill.getSelection().index;// 插入圖片? res.url為服務(wù)器返回的圖片地址quill.insertEmbed(length, "image", res.url);// 調(diào)整光標(biāo)到最后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: "標(biāo)題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: "標(biāo)題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: "標(biāo)題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: "標(biāo)題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: "標(biāo)題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: "標(biāo)題6"; }.ql-snow .ql-picker.ql-font .ql-picker-label::before, .ql-snow .ql-picker.ql-font .ql-picker-item::before {content: "標(biāo)準(zhǔn)字體"; } .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>

封裝完組件后就是在需要用到的頁面進(jìn)行引用,比如這里是在通知和公告的新增和編輯頁面使用。

來到此vue頁面,首先在頁面中引入該組件

import Editor from '@/components/Editor' ;

然后聲明該組件

export default {name: "Notice",components: {Editor},

此頁面為發(fā)布通知和公告的頁面,所以在新增和編輯時的位置添加該組件

????????? <el-col :span="24"><el-form-item label="內(nèi)容"><Editor v-model="form.noticeContent" /></el-form-item></el-col>

這里的form.noticeContent就是在點(diǎn)擊編輯頁面時從后臺數(shù)據(jù)庫中查詢的保存的富文本編輯器的內(nèi)容。

設(shè)計(jì)一個公告的數(shù)據(jù)庫,添加存儲內(nèi)容的字段

?

這樣就能實(shí)現(xiàn)富文本編輯器的內(nèi)容的存儲和回顯以及帶照片的上傳。

總結(jié)

以上是生活随笔為你收集整理的Vue中使用vue-quil-editor富文本编辑器+el-upload实现带图片上传到SpringBoot后台接口的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。