参考大佬思路:改造vue-quill-editor:实现图片上传到服务器再插入富文本 · Issue #2 · NextBoy/skill · GitHub
概述
1、Element UI:上传使用的是Element 的el-upload
组件。
2、quill-editor:富文本处理。
前期准备
1、七牛云指定空间的上传token,得通过服务器获取。
func GetToken() string {
putPolicy := storage.PutPolicy{
//七牛云对象存储空间名称
Scope: QinNiuVideoScope,
//token过期时间
Expires: uint64(time.Now().AddDate(0,0,1).Unix()),
}
mac := qbox.NewMac(accessKey, secretKey)
return putPolicy.UploadToken(mac)
}
2、七牛云指定空间的域名,需公开空间,否则无法展示。
3、上传地址,根据七牛云服务器所在地区选择。如华东机房:
// regionHuadong 表示华东机房
regionHuadong = Region{
SrcUpHosts: []string{
"up.qiniup.com",
"up-nb.qiniup.com",
"up-xs.qiniup.com",
},
CdnUpHosts: []string{
"upload.qiniup.com",
"upload-nb.qiniup.com",
"upload-xs.qiniup.com",
},
RsHost: "rs.qbox.me",
RsfHost: "rsf.qbox.me",
ApiHost: "api.qiniu.com",
IovipHost: "iovip.qbox.me",
}
前端代码
1、组件:squill-editor-qiniu.vue
<template>
<div id="quillEditorQiniu">
<!-- 基于elementUi的上传组件 el-upload begin-->
<el-upload
class="avatar-uploader"
:action="uploadUrl"
:accept="'image/*'"
:data="qiniuForm"
:show-file-list="false"
:on-success="uploadEditorSuccess"
:on-error="uploadEditorError"
:before-upload="beforeEditorUpload"
>
</el-upload>
<el-upload
class="video-uploader"
:action="uploadUrl"
accept=".mp4"
:data="qiniuForm"
:show-file-list="false"
:on-success="uploadEditorVideoSuccess"
:on-error="uploadEditorError"
:before-upload="beforeEditorVideoUpload"
>
</el-upload>
<!-- 基于elementUi的上传组件 el-upload end-->
<quill-editor
class="editor"
v-model="content"
ref="customQuillEditor"
:options="editorOption"
>
</quill-editor>
</div>
</template>
<script>
import { string } from "clipboard";
import { quillEditor } from "vue-quill-editor";
//自定义编辑器的工作条
const toolbarOptions = [
["bold", "italic", "underline", "strike"], // toggled buttons
["blockquote", "code-block"],
[{ header: 1 }, { header: 2 }], // custom button values
[{ list: "ordered" }, { list: "bullet" }],
[{ script: "sub" }, { script: "super" }], // superscript/subscript
[{ indent: "-1" }, { indent: "+1" }], // outdent/indent
[{ direction: "rtl" }], // text direction
[{ size: ["small", false, "large", "huge"] }], // custom dropdown
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }], // dropdown with defaults from theme
[{ font: [] }],
[{ align: [] }],
["link", "image", "video"],
["clean"], // remove formatting button
];
export default {
data() {
return {
quillUpdateImg: false,
quillUpdateVideo: false,
content: "",
editorOption: {
placeholder: "请填写详情信息",
modules: {
toolbar: {
container: toolbarOptions, // 工具栏
handlers: {
image: function (value) {
if (value) {
document
.querySelector("#quillEditorQiniu .avatar-uploader input")
.click();
} else {
this.quill.format("image", false);
}
},
video: function (value) {
if (value) {
document
.querySelector("#quillEditorQiniu .video-uploader input")
.click();
} else {
this.quill.format("video", false);
}
},
},
},
},
},
qiniuForm: {
key: "",
token: "",
showUrl: "",
},
};
},
props: {
token: String, //七牛云上传的token,类型为String
uploadUrl: String, //从七牛云上拿到自己的上传地址,类型为String
showUrl: string,
},
methods: {
//上传图片之前
beforeEditorUpload(file) {
//显示上传动画
this.qiniuForm.key =
new Date().getTime() + "" + Math.floor(Math.random() * 1000) + ".png";
this.quillUpdateImg = true;
},
beforeEditorVideoUpload(file) {
//显示上传动画
this.qiniuForm.key =
new Date().getTime() + "" + Math.floor(Math.random() * 1000) + ".mp4";
this.quillUpdateVideo = true;
},
// 上传图片成功
uploadEditorSuccess(res, file) {
//拼接出上传的图片在服务器的完整地址
let imgUrl = this.qiniuForm.showUrl + res.key;
//重置上传文件key,为下次上传做好准备
this.qiniuForm.key =
new Date().getTime() + "" + Math.floor(Math.random() * 1000);
// 获取富文本组件实例
let quill = this.$refs.customQuillEditor.quill;
// 获取光标所在位置
let length = quill.getSelection().index;
// 插入图片 res.info为服务器返回的图片地址
quill.insertEmbed(length, "image", imgUrl);
// 调整光标到最后
quill.setSelection(length + 1);
//取消上传动画
this.quillUpdateImg = false;
},
uploadEditorVideoSuccess(res, file) {
//拼接出上传的图片在服务器的完整地址
let imgUrl = this.qiniuForm.showUrl + res.key;
//重置上传文件key,为下次上传做好准备
this.qiniuForm.key =
new Date().getTime() + "" + Math.floor(Math.random() * 1000);
// 获取富文本组件实例
let quill = this.$refs.customQuillEditor.quill;
// 获取光标所在位置
let length = quill.getSelection().index;
// 插入图片 res.info为服务器返回的图片地址
quill.insertEmbed(length, "video", imgUrl);
// 调整光标到最后
quill.setSelection(length + 1);
//取消上传动画
this.quillUpdateVideo = false;
},
// 上传图片失败
uploadEditorError(res, file) {
//页面提示
Notification.error({
message: "上传失败",
});
//取消上传动画
this.quillUpdateImg = false;
this.quillUpdateVideo = false;
},
},
mounted() {
this.qiniuForm.token = this.token;
this.qiniuForm.showUrl = this.showUrl;
},
watch: {
content(newVal, oldVal) {
this.$emit("input", newVal);
},
},
};
</script>
<style scoped>
.editor {
min-height: 200px;
margin-bottom: 60px;
}
</style>
2、组件使用:
//引用组件
import SquillEditorQiniu from "@/components/squill-editor-qiniu.vue";
//表单使用
<el-form-item label="内容:" prop="content">
<squill-editor-qiniu
token=""
v-model="formData.content"
showUrl="http://video.yihaitian.cn/"
uploadUrl="http://up.qiniup.com/"
></squill-editor-qiniu>
</el-form-item>