上传组件优化el-upload组件结合上传阿里云OSS实现更优交互

Posted 黑子Kuroko

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了上传组件优化el-upload组件结合上传阿里云OSS实现更优交互相关的知识,希望对你有一定的参考价值。

1、效果展示

2、实现代码

在components目录下,新建组件 myImgUpload.vue,代码如下:

<template>
    <div>
        <el-upload
            :class="disabled ? 'hideAdd' : 'showAdd'"
            ref="myImgUpload"
            list-type="picture-card"
            :multiple="limit > 1"
            :disabled="disabled"
            :file-list="fileList"
            :accept="accept"
            :limit="limit"
            :on-exceed="onExceed"
            :action="action"
            :data="params"
            :before-upload="beforeUpload"
            :on-success="onSuccess"
            :on-remove="onRemove"
            :on-error="onError"
            :on-preview="onPreview"
            :with-credentials="true">
            <i class="el-icon-plus"></i>
        </el-upload>
        <el-dialog :visible.sync="dialogVisible" append-to-body>
            <img width="100%" :src="dialogImageUrl" alt="">
        </el-dialog>
        <div v-if='tip' class="tip">tip</div>
    </div>
</template>

<script>
    export default 
        props: 
            action: 
                type: String,
                default: `$window.baseUrlweb/upload/getAvatarUploadInfo`
            ,
            value: 
                type: String,
                default: ''
            ,
            fileList: null,
            isEdit: 
                type: Boolean,
                default: false
            ,
            tip: 
                type: String,
                default: ''
            ,
            disabled: 
                type: Boolean,
                default: false
            ,
            // 限制上传数量,默认是1张
            limit: 
                type: Number,
                default: 1
            ,
            // 限制上传大小,默认是5M
            maxsize: 
                type: Number,
                default: 5
            ,
            // 限制上传文件格式,默认是1 - 图片
            // 文件类型:1:图片(.jpg/.png) ;2:so文件/txt文件上传(.so/.txt);3:provision文件上传(.mobileprovision)
            fileType: 
                type: Number,
                default: 1
            
        ,
        data() 
            return 
                params: 
                    'fileType': 1,
                    'fileName': 'default.jpg'
                ,
                dialogImageUrl: '',
                dialogVisible: false,
                accept: ''
            
        ,
        created() 
            switch (this.fileType) 
            case 1:
                this.accept = 'image/*'
                break
            default:
                this.accept = '*'
            
        ,
        methods: 
            uploadAliyun(res, file) 
                if (res.code === '000') 
                    let objectName = res.data.key
                    let OSS = require('ali-oss')
                    let client = new OSS(
                        region: res.data.regionId,
                        accessKeyId: res.data.accessKeyId,
                        accessKeySecret: res.data.accessKeySecret,
                        stsToken: res.data.securityToken,
                        bucket: res.data.bucket
                    )
                    const put = async() => 
                        try 
                            let result = await client.put(objectName, file.raw)
                            if (result.res.statusCode === 200) 
                                console.log('上传阿里云成功')
                                // this.$message.success('上传成功')
                             else 
                                this.$message.error('上传阿里云失败')
                            
                         catch (e) 
                            this.$message.error(e)
                        
                    
                    put()
                 else 
                    this.$message.error(res.message)
                
            ,
            clearFiles () 
                this.$refs.myImgUpload.clearFiles()
            ,
            beforeUpload(file) 
                this.params.fileName = file.name
                const isJPG = file.type === 'image/jpeg'
                const isPNG = file.type === 'image/png'
                const isRightSize = file.size / 1024 / 1024 < this.maxsize
                if (!isJPG && !isPNG) 
                    this.$message.error('上传头像图片只能是 JPG 或 PNG 格式!')
                
                if (!isRightSize) 
                    this.$message.error('上传图片大小不能超过最大限制!')
                
                return (isJPG || isPNG) && isRightSize
            ,
            onSuccess(res, file, fileList) 
                this.$message.success('上传成功')
                let val = ''
                fileList.forEach(item => 
                    if (val !== '') 
                        val += ','
                    
                    if (item.response) 
                        val += item.response.data.downloadPath
                     else 
                        val += item.url
                    
                )
                this.$emit('input', val)
                this.uploadAliyun(res, file)
            ,
            onPreview(file) 
                this.dialogImageUrl = file.url
                this.dialogVisible = true
            ,
            onExceed(files, fileList) 
                this.$message(
                    message: '上传数量超出最大限制!',
                    type: 'warning'
                )
            ,
            onRemove(res, fileList) 
                let val = ''
                fileList.forEach(item => 
                    if (val !== '') 
                        val += ','
                    
                    if (item.response) 
                        val += item.response.data.downloadPath
                     else 
                        val += item.url
                    
                )
                this.$emit('input', val)
            ,
            onError(err) 
                console.log('this is onError:\\n', err)
            
        
    
</script>

<style lang='less' scope>
    .tip 
        color: #606266;
        font-size: 12px;
    
    .hideAdd 
        .el-upload--picture-card 
            display: none;
        
    
    .showAdd 
        .el-upload--picture-card 
            display: block;
        
    
</style>

3、设计思路:

在之前的一篇文章中(【上传文件】基于阿里云的视频点播VOD、对象存储OSS实现音视频图片等文件上传),我们用了一个简单的 el-button 结合原生 input 来实现了上传文件至阿里云,但是交互上存在诸多漏洞,比方说我上传了一张图片之后只能替换无法删除;上传成功之后无法预览图片等等。所以,这次我们基于 el-upload 来更好地去实现这个上传功能,交互上也表现地更合理些。

实现的关键在于对 el-upload上传生命周期 的理解,在合适的时间上做合适的事情!比如:在合适的时间(beforeUpload)对文件格式做校验,在合适的时间(onSuccess)上传文件至阿里云OSS,在合适的时间(onSuccess/onRemove)与父组件通信(this.$emit('input', val))。

 

 

 

 

 

 

 

 

以上是关于上传组件优化el-upload组件结合上传阿里云OSS实现更优交互的主要内容,如果未能解决你的问题,请参考以下文章

富文本vue-quill-editor结合element UI--upload做图片上传至七牛云服务器(含node后端)

遍历生成el-upload上传组件及遍历回填el-upload上传数据

elemetUi 组件--el-upload

阿里云oss 前端+后台方式-前端部分el-upload

基于element-ui封装上传图片到腾讯云Cos组件

el-upload怎么中途改变上传地址