vue富文本图片通过STS直传阿里云OSS

注意:此解决方案并不完美,无法实现粘贴图片功能
可移步支持粘贴图片的解决方案: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 {
                // 提示上传失败信息
            }
        },
    },
    // ...其他代码
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容