该案例的情况
quill-image-extend-module功能:
本意呢,是打算将整个富文本的数据
都上传到阿里云服务器上,但是把 Quill 数据封装进 fromData 中上传时,总是报错,报错信息是 Required request part 'file' is not present
,如下
这个问题应该是前端传参和后台接收参数不一致的问题,和我的后台协商之后,发现并没有什么不妥之处,因为通过 el-upload 上传图片也是通过 formData 数据,是可以成功上传的。研究考虑一番之后,决定放弃此方式,改用存储数据库来实现,将富文本中插入的图片上传服务器、富文本的 html 字符串存储数据库
。之所以将图片上传服务器,还有另一个原因,就是如果直接将富文本的 html 字符串存储数据库的话,富文本中插入的图片会以 base64 格式存储,占空间太大;而将图片上传服务器,把返回的图片地址以 存入富文本的 html 字符串中,可以大大缩小空间。下面上两张图对比一下
base64 格式:(截图没有截下全部,大概31kb)
图片地址格式:
好了,来龙去脉记录完毕,下面开始说说如何实现
npm install vue-quill-editor --save-dev
npm install quill-image-extend-module --save-dev
注:在下面的使用过程中,如果出现 modules 里面缺少相关依赖,直接在项目中执行 npm install,就可以
import { quillEditor, Quill } from 'vue-quill-editor'
import { container, ImageExtend, QuillWatch } from 'quill-image-extend-module'
Quill.register('modules/ImageExtend', ImageExtend)
由于是第一次做这个功能,百度了很多,测试了两种方法。下面对这两种方法进行分析
<template>
<div class="testuploadquillpicandback">
<quill-editor @change="onEditorChange($event)"
id="desc" ref="quill" v-model="desc" :options="editorOption">
</quill-editor>
</div>
</template>
<script>
import { quillEditor, Quill } from 'vue-quill-editor'
import { container, ImageExtend, QuillWatch } from 'quill-image-extend-module'
Quill.register('modules/ImageExtend', ImageExtend)
export default{
data() {
return {
desc: '',
editorOption: {
placeholder: '此处输入赛事规程',
modules: {
ImageExtend: {
loading: true,
name: 'file',//图片参数名
size: 1, // 可选参数 图片大小,单位为M,1M = 1024kb
action: '/feelings/common/upload/file',//上传的服务器地址,如果action为空,则采用base64插入图片
// response 为一个函数,用来获取服务器返回的具体图片地址
response: res => {
console.log(res)
const imgUrl = 'http://' + res.data
return imgUrl
},
headers: xhr => {
// 上传图片请求需要携带token的 在xhr.setRequestHeader中设置,这里我的token存放在sessionStorage中
xhr.setRequestHeader("token", window.sessionStorage.getItem('token'))
},
// 可选参数 设置请求头部
sizeError: () => {}, // 图片超过大小的回调
start: () => {}, // 可选参数 自定义开始上传触发事件
end: () => {}, // 可选参数 自定义上传结束触发的事件,无论成功或者失败
error: () => {}, // 可选参数 上传失败触发的事件
success: () => {
console.log('ImageExtend中的success:上传成功')
}, // 可选参数 上传成功触发的事件
change: (xhr, formData) => {
// xhr.setRequestHeader('myHeader','myValue')
// formData.append('token', 'myToken')
} // 可选参数 每次选择图片触发,也可用来设置头部,但比headers多了一个参数,可设置formData
},
// 如果不上传图片到服务器,此处不必配置
toolbar: {
// container为工具栏,此次引入了全部工具栏,也可自行配置
container: [
["bold", "italic", "underline", "strike"],
["blockquote", "code-block"],
[{ header: 1 }, { header: 2 }],
[{ list: "ordered" }, { list: "bullet" }],
[{ script: "sub" }, { script: "super" }],
[{ indent: "-1" }, { indent: "+1" }],
[{ direction: "rtl" }],
[{ size: ["small", false, "large", "huge"] }],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }],
[{ font: [] }],
[{ align: [] }],
["image"]
],
// 上传成功,回显图片(会进入如上面ImageExtend的各过程,返回)
handlers: {
image: function() {
// 劫持原来的图片点击按钮事件
QuillWatch.emit(this.quill.id)
}
}
}
}
},
}
},
methods: {
// quill的change事件
onEditorChange(e) {
console.log('onEditorChange打印e')
console.log(e)
}
}
}
</script>
参考自:https://www.cnblogs.com/dachengzizi/p/11805488.html
<template>
<div class="testuploadquillpicandback">
<quill-editor @change="onEditorChange($event)"
id="desc" ref="quill" v-model="desc">
</quill-editor>
</div>
</template>
<script>
import { quillEditor, Quill } from 'vue-quill-editor'
import { container, ImageExtend, QuillWatch } from 'quill-image-extend-module'
Quill.register('modules/ImageExtend', ImageExtend)
export default{
data() {
return {
desc: ''
}
},
methods: {
// quill的change事件
onEditorChange(e) {
console.log('onEditorChange打印e')
console.log(e)
}
}
}
</script>
<style>
</style>
参考自:https://www.cnblogs.com/bingchenzhilu/p/11951571.html
<template>
<div class="testuploadquillpicandback">
<quill-editor @change="onEditorChange($event)"
id="desc" ref="quill" v-model="desc" :options="editorOption">
</quill-editor>
// 实际使用时,可以隐藏以得到更好的体验
<input type="file" @change="change" id="upload" />
</div>
</template>
<script>
import { quillEditor, Quill } from 'vue-quill-editor'
import { container, ImageExtend, QuillWatch } from 'quill-image-extend-module'
Quill.register('modules/ImageExtend', ImageExtend)
export default{
data() {
return {
desc: '',
editorOption: {
placeholder: '此处输入赛事规程',
modules: {
ImageExtend: {
loading: true,
name: 'file',//图片参数名
size: 1, // 可选参数 图片大小,单位为M,1M = 1024kb
action: '/feelings/common/upload/file',//上传的服务器地址,如果action为空,则采用base64插入图片
// response 为一个函数,用来获取服务器返回的具体图片地址
response: res => {
console.log('ImageExtend中的response')
console.log(res)
const imgUrl = 'http://' + res.data
return imgUrl
},// 注意:原作者中的res.data和我的不一样,我的res.data=图片地址
headers: xhr => {
// 上传图片请求需要携带token的 在xhr.setRequestHeader中设置
xhr.setRequestHeader("token", window.sessionStorage.getItem('token'))
},
// 可选参数 设置请求头部
sizeError: () => {}, // 图片超过大小的回调
start: () => {}, // 可选参数 自定义开始上传触发事件
end: () => {}, // 可选参数 自定义上传结束触发的事件,无论成功或者失败
error: () => {}, // 可选参数 上传失败触发的事件
success: () => {
console.log('ImageExtend中的success:上传成功')
}, // 可选参数 上传成功触发的事件
change: (xhr, formData) => {} // 可选参数 每次选择图片触发,也可用来设置头部,但比headers多了一个参数,可设置formData
},
// 如果不上传图片到服务器,此处不必配置
toolbar: {
// container为工具栏,此次引入了全部工具栏,也可自行配置
container: [
["bold", "italic", "underline", "strike"],
["blockquote", "code-block"],
[{ header: 1 }, { header: 2 }],
[{ list: "ordered" }, { list: "bullet" }],
[{ script: "sub" }, { script: "super" }],
[{ indent: "-1" }, { indent: "+1" }],
[{ direction: "rtl" }],
[{ size: ["small", false, "large", "huge"] }],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }],
[{ font: [] }],
[{ align: [] }],
["image"]
],
// 进入input的change事件,可以实现上传,但是不能把返回的图片地址插入到quill内容中
handlers: {
image: function(value) {
if (value) {
// 劫持原来的图片点击按钮事件,#upload即为自己写的上传,可以使用最简单的input
document.querySelector('#upload').click()
} else {
this.quill.format('image', false)
}
}
}
}
}
},
}
},
methods: {
// quill的change事件
onEditorChange(e) {
console.log('onEditorChange打印e')
console.log(e)
},
// input的change事件:可以实现上传,但是不能把返回的图片地址插入到quill内容中
async change(e) {
console.log('input的change事件')
let file = e.target.files[0]
const formData = new FormData()
formData.append('file', file)
// 下面可以根据后端写的上传接口进行传递参数
const { data: res } = await this.$http.post('/feelings/common/upload/file', formData)
console.log(res)
if (res.code !== 200) {
this.$message.error('上传失败')
}
this.$message.success('上传成功')
}
}
}
</script>
<style>
</style>