注意:此解决方案并不完美,无法实现粘贴图片功能
可移步支持粘贴图片的解决方案:https://www.jianshu.com/p/a2ac665601f3
借鉴文章:https://blog.csdn.net/weixin_43796132/article/details/106839459
项目需求:
后台新闻模块内容中可能会有大量图片,为优化用户体验,富文本编辑器需要使用OSS托管图片。
安装组件
// 安装quill富文本 vue版本
npm install vue-quill-editor
// 安装阿里云oss sdk
npm install --save ali-oss
开始写代码
<template>
<div>
<quill-editor
style="height: 300px; margin-top: -25px"
v-model="form.content"
ref="myQuillEditor"
:options="editorOption"
>
</quill-editor>
// 此处使用的是传统的文件选择模式,也可以把此处的文件选择上传逻辑修改为你自己的
<input type="file" id="f" @change="fileSelect" />
</div>
</template>
// 组件引入
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
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 {
components: {
quillEditor,
},
data() {
return {
// OSS STS数据
ossData: [],
// form数据
form: {
content: "",
},
// 富文本自定义配置项
editorOption: {
modules: {
toolbar: {
container: toolbarOptions, // 工具栏
handlers: {
// 此处开始改写自带的图片上传
image: (value) => {
if (value) {
// 当点击富文本中的图片按钮时,模拟点击自定义的图片选择器
document.getElementById("f").click();
} else {
this.quill.format("image", false);
}
},
},
},
},
},
};
},
computed: {
editor() {
return this.$refs.myQuillEditor.quill;
},
},
created(){
this.getStsData();
},
methods: {
// 获取STS数据
getStsData(){
this.ossData="通过ajax请求后端获取STS数据后赋给this.ossData,后面会用到";
},
// 选择图片后触发此方法开始上传
fileSelect() {
const OSS = require("ali-oss");
const client = new OSS({
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
region: "oss-cn-beijing",
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
accessKeyId: this.ossData.AccessKeyId,
accessKeySecret: this.ossData.AccessKeySecret,
// 从STS服务获取的安全令牌(SecurityToken)。
stsToken: this.ossData.SecurityToken,
refreshSTSToken: async () => {
// 向您搭建的STS服务获取临时访问凭证。
const info = await fetch(this.ossData.StsServer);
return {
accessKeyId: info.accessKeyId,
accessKeySecret: info.accessKeySecret,
stsToken: info.stsToken,
};
},
// 刷新临时访问凭证的时间间隔,单位为毫秒。
refreshSTSTokenInterval: 300000,
// 填写Bucket名称。
bucket: this.ossData.bucket,
});
// 从输入框获取file对象,例如<input type="file" id="file" />。
const data = document.getElementById("f").files[0];
// 创建并填写Blob数据。
//const data = new Blob('Hello OSS');
// 创建并填写OSS Buffer内容。
//const data = new OSS.Buffer('Hello OSS');
let _this = this;
async function putObject() {
try {
// 填写Object完整路径。Object完整路径中不能包含Bucket名称。
// 您可以通过自定义文件名(例如exampleobject.txt)或文件完整路径(例如exampledir/exampleobject.txt)的形式实现将数据上传到当前Bucket或Bucket中的指定目录。
// data对象可以自定义为file对象、Blob数据或者OSS Buffer。
const result = await client.put(
"textareaImage/" + _this.createFileName(32),
data
);
console.log(result);
// 在富文本中插入图片
_this.textareaInsertImage(result.url);
} catch (e) {
console.log(e);
alert("图片上传失败,请稍后重试");
}
}
putObject();
},
// 富文本插入图片
textareaInsertImage(url) {
let quill = this.$refs.myQuillEditor.quill;
// 如果上传成功
if (url) {
// 获取光标所在位置
let length = quill.getSelection().index;
// 插入图片,res为服务器返回的图片链接地址
quill.insertEmbed(length, "image", url);
// 调整光标到最后
quill.setSelection(length + 1);
} else {
// 提示上传失败信息
}
},
},
// ...其他代码
}