Vue搭配富文本WangEditor3.1.1实现直传图片到OSS

感谢

  • 首先要感谢网上一些大佬分享的部分代码给我的工作提供了一些参考,让我能够把有效的代码整合到一起,实现想要的功能,在这里与大家分享!感谢!

功能截图

clipboard.png

  • 富文本添加图片保存到OSS也是这几天项目中刚刚遇到的,前期没怎么想下决心搞一搞,说实话呢也是不会搞,今天呢终于是一点一点的给整了出来,在这里呢与大家分享一下,网上可能有一些Vue整合Wangeditor上传图片的文章,大家呢可以参考着看!废话不多说,直接上项目

项目参考

码云地址

项目结构解析与部分代码展示

  • 必要的静态文件

clipboard.png

clipboard.png

  • wangeditor编辑器搭建 npm先下载就不用说了吧
<template lang="html">
  <div class="editor">
    <div ref="toolbar" class="toolbar">
    </div>
    <div ref="editor" class="text">
    </div>
  </div>
</template>

<script>
import E from 'wangeditor'
import {UPLOADER} from '@t/utils'
export default {
    name: 'Editorbar',
    data() {
        return {
            editor: null,
            info_: null,
            UPLOADER,
        }
    },
    model: {
        prop: 'value',
        event: 'change',
    },
    props: {
        value: {
            type: String,
            default: '',
        },
        isClear: {
            type: Boolean,
            default: false,
        },
    },
    watch: {
        isClear(val) {
            // 触发清除文本域内容
            if (val) {
                this.editor.txt.clear()
                this.info_ = null
            }
        },
        value(val) {
            // 使用 v-model 时,设置初始值
            this.editor.txt.html(val)
        },
    },
    mounted() {
        this.seteditor()
        this.editor.config.customUploadInit = this.UPLOADER(this.editor).init()
    },
    methods: {
        seteditor() {
            this.editor = new E(this.$refs.toolbar, this.$refs.editor)
            // 配置菜单
            this.editor.customConfig.menus = [
                'head', // 标题
                'bold', // 粗体
                'fontSize', // 字号
                'fontName', // 字体
                'italic', // 斜体
                'underline', // 下划线
                'strikeThrough', // 删除线
                'foreColor', // 文字颜色
                'backColor', // 背景颜色
                'link', // 插入链接
                'list', // 列表
                'justify', // 对齐方式
                'quote', // 引用
                'emoticon', // 表情
                'image', // 插入图片
                'table', // 表格
                // 'video', // 插入视频
                'code', // 插入代码
                'undo', // 撤销
                'redo', // 重复
            ]

            this.editor.customConfig.onchange = html => {
                this.info_ = html // 绑定当前逐渐地值
                this.$emit('change', this.info_) // 将内容同步到父组件中
            }

            // 创建富文本编辑器
            this.editor.create()
        },
    },
}
</script>

<style lang="css">
.editor {
    width: 80%;
    margin: 0 auto;
}
.toolbar {
    border: 1px solid #ccc;
}
.text {
    border: 1px solid #ccc;
    height: 500px;
}
</style>
  • 上传OSS方法的封装

clipboard.png

const OSSConfig = {
    ossParams: {
        key: '', // key后面有用,先默认设空字符串
        success_action_status: '200', // 默认200
        accessKeyId: '你的KeyID',
        accessKeySecret: '你的Key',
        bucket: 'Bucket',
        host: 'OSS上传地址',
    },
}

var g_object_name, new_multipart_params, suffix

// ==========================================================这一串是为了文件的名字?====================================================//
function random_string(len) {
    len = len || 32
    var chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
    var maxPos = chars.length
    var pwd = ''
    for (let i = 0; i < len; i++) {
        pwd += chars.charAt(Math.floor(Math.random() * maxPos))
    }
    return pwd
}

function get_suffix(filename) {
    let pos = filename.lastIndexOf('.')
    let fname = ''
    if (pos != -1) {
        fname = filename.substring(pos)
    }
    return fname
}

function calculate_object_name(filename) {
    suffix = get_suffix(filename)
    g_object_name = OSSConfig.ossParams.key + random_string(20) + suffix
    return ''
}

function set_upload_param(up, filename, ret) {
    g_object_name = OSSConfig.ossParams.key
    if (filename != '') {
        suffix = get_suffix(filename)
        calculate_object_name(filename)
    }
    var policyText = {
        expiration: '2020-01-01T12:00:00.000Z', //设置该Policy的失效时间,超过这个失效时间之后,就没有办法通过这个policy上传文件了
        conditions: [
            ['content-length-range', 0, 1048576000], // 设置上传文件的大小限制
        ],
    }
    var policyBase64 = Base64.encode(JSON.stringify(policyText))
    let message = policyBase64
    var bytes = Crypto.HMAC(Crypto.SHA1, message, OSSConfig.ossParams.accessKeySecret, {asBytes: true})
    var signature = Crypto.util.bytesToBase64(bytes)
    new_multipart_params = {
        key: g_object_name,
        policy: policyBase64,
        OSSAccessKeyId: OSSConfig.ossParams.accessKeyId,
        success_action_status: 200, //让服务端返回200,不然,默认会返回204
        bucket: OSSConfig.ossParams.bucket,
        signature: signature,
    }

    up.setOption({
        url: OSSConfig.ossParams.host,
        multipart_params: new_multipart_params,
    })

    up.start()
}
// ==========================================================这一串是为了文件的名字?====================================================//

var UPLOADER = editor => {
    let uploader = new plupload.Uploader({
        runtimes: 'html5,flash,silverlight,html4',
        browse_button: editor.imgMenuId,
        multi_selection: true,
        auto_start: true,
        // 我也不知道这是干啥的 以后慢慢研究,注释掉倒是没啥影响
        // flash_swf_url: '../../public/lib/plupload-2.1.2/js/Moxie.swf',
        // silverlight_xap_url: '../../public/lib/plupload-2.1.2/js/Moxie.xap',
        url: OSSConfig.ossParams.host,

        filters: {
            mime_types: [
                //只允许上传图片和zip,rar文件
                {title: 'Image files', extensions: 'jpg,jpeg,gif,png,bmp'},
                {title: 'video files', extensions: 'mp4,3gp'},
            ],
            max_file_size: '10mb', //最大只能上传10mb的文件
            prevent_duplicates: false, //不允许选取重复文件
        },

        init: {
            PostInit: function() {
                set_upload_param(uploader, '', false)
                return false
            },

            BeforeUpload: function(up, file) {
                set_upload_param(up, file.name, true)
            },

            FilesAdded: function(up) {
                up.start() //选择完后直接上传
            },

            FileUploaded: function(up, file, info) {
                if (info.status == 200) {
                    var file_type = file.type
                    var is_image = file_type.indexOf('image')
                    var is_video = file_type.indexOf('video')
                    if (is_image > -1) {
                        editor.cmd.do(
                            'insertHtml',
                            '<img src="' +
                                OSSConfig.ossParams.host +
                                '/' +
                                g_object_name +
                                '" style="width: auto; max-width:100%;"/>',
                        )
                    }

                    // if (is_video > -1) {
                    //     editor.cmd.do(
                    //         'insertHtml',
                    //         '<video controls src="' +
                    //             _this.ossParams.host +
                    //             _this.g_object_name +
                    //             '" style="width: auto; max-width:100%;"></video>',
                    //     )
                    // }
                } else {
                    alter(info.response)
                }
            },

            Error: function(up, err) {
                if (err.code == -600) {
                    alter('\n选择的文件太大了,可以根据应用情况,在upload.js 设置一下上传的最大大小')
                } else if (err.code == -601) {
                    alter('\n选择的文件后缀不对,可以根据应用情况,在upload.js进行设置可允许的上传文件类型')
                } else if (err.code == -602) {
                    alter('\n这个文件已经上传过一遍了')
                } else {
                    alter('\nError xml:' + err.response)
                }
            },
        },
    })
    return uploader
}

export {UPLOADER}
  • 调用

clipboard.png

mounted() {
        this.seteditor()
        this.editor.config.customUploadInit = this.UPLOADER(this.editor).init()
    },

总结

整个东西呢历时几个小时,代码没做太多的优化,希望大家可以提示宝贵意见~谢谢!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值