elementui-Upload-实现自动上传

1,340 阅读1分钟

Upload-实现自动上传

实现效果

image.png

image.png

  1. 实现了图片上传,预发,删除
  2. 控制了图片上传格式,大小
  3. 重点: 解决了同时上传多张的时候,错误提示重叠问题

展示代码

页面

<template>
    <div>
        <el-upload class="kh-upload" ref="upload" :disabled="uploadLoading" list-type="picture-card" :auto-upload="true"
            :action="upload.action" :data="uploadDataObj" :file-list="fileList" :before-upload="beforeUploadHandle"
            :on-exceed="onExceedHandle" :on-error="onErrorHandle" :on-success="onSuccessHandle"
            :on-remove="onRemoveHandle" :on-progress="onProgressHandle" :on-change="onChangeHandle"
            :limit="upload.limit" :accept="upload.accept" multiple>
            <i slot="default" class="el-icon-plus"></i>
            <div slot="file" slot-scope="{file}">
                <img v-if="!file.progressFlag" class="el-upload-list__item-thumbnail" :src="file.url" alt=""
                    style="object-fit: cover;position: absolute;width: 100%;height: 100%;left: 0;top: 0;">
                <el-progress v-if="file.progressFlag" type="circle" :percentage="file.progressPercent"></el-progress>
                <span class="el-upload-list__item-actions">
                    <span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
                        <i class="el-icon-view"></i>
                    </span>
                </span>
                <!-- 删除图片 -->
                <div class="del-img" style=""><i class="el-icon-error" @click="delImgHandle(file)"></i></div>
            </div>
        </el-upload>
    </div>
</template>

数据和定义方法

<script>
import { reqQiniuToken } from 'xxx'; //后端上传接口
import eventBus from '../eventBus' //通过eventBus,进行数据通信

export default {
    props: {
        type: String
    },
    data () {
        return {
            fileList: [],
            needUploadList: [],
            upload: {
                limit: 10,//图片大小
                action: 'http://upload.qiniup.com', //图片上传存放位置
                accept: '.jpg,.jpeg,.png,.gif,.psd,.JPG,.JPEG,.PNG,.GIF,.PSD' //图片格式
            },
            dialogImageUrl: '',
            dialogVisible: false,
            disabled: false,
            uploadDataObj: {},
            domainUrl: '', // 图片主地址
            timer: null,
            uploadLoading: false

        }
    },
    mounted () {
        eventBus.$on('edit-customer-upload', (val) => {
            if (this.type === 'edit') {
                this.uploadLoading = val.uploadLoading
                this.domainUrl = val.domainUrl || ''
                this.uploadDataObj = val.uploadDataObj || {}
                this.fileList = val.needList
            }
        })
    },
    beforeDestroy () {
        eventBus.$off('edit-customer-upload') // eventBus 需要销毁,不然会调用多次
    },
    methods: {
        onRemoveHandle (file, fileList) {
            this.fileList = fileList
            this.$emit('fileList', this.fileList)
        },
        delFile (file) {
            let findIndex = this.fileList.findIndex(v => v.uid === file.uid)
            if (findIndex !== -1) {
                this.fileList.splice(findIndex, 1)
            }
            this.$emit('fileList', this.fileList)
        },
        // 移除图片
        delImgHandle (file) {
            this.$confirm('确定要删除当前上传文件吗?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.delFile(file)
            }).catch(() => {

            })
        },
        handlePictureCardPreview (file) {
            if (file.progressPercent === 100) {
                let url = `${this.domainUrl}${file.response.key}`
                window.open(url)
            } else {
                this.$message({
                    type: 'error',
                    message: '文件上传中,无法查看图片'
                })
            }

        },
        onChangeHandle (file, fileList) {
            if (file.status === 'ready') {
                this.$set(file, 'progressFlag', true)
                this.$set(file, 'progressPercent', 0)
                this.fileList.push(file)
                this.$emit('fileList', this.fileList)
            }
        },
        // 上传之前 auto-upload:false,不自动上传则不触发 before-upload 钩子
        beforeUploadHandle (file) {
            if (this.timer) window.clearTimeout(this.timer)

            if (this.type === 'edit') {
                if (!this.uploadDataObj.token) {                    
                    setTimeout(async () => {
                        await this.$message({
                            customClass: 'upload-tip',
                            type: 'error',
                            message: `上传的图片token不存在,请稍后重试`,
                        })
                    })
                    return false
                }
            }

            return new Promise(async (resolve, reject) => {
                let fSize = file.size / (1024 * 1024)
                let limitSize = 10
                if (fSize > limitSize) {
                   // 重点代码: 解决了上传多张时候,错误提示错误时候,会重叠
                    setTimeout(async () => {
                        await this.$message({
                            customClass: 'upload-tip',
                            type: 'error',
                            message: `"${file.name}"的照片,当前文件大于${limitSize}M`,
                        })
                    })
                    return reject(false)

                }
                var fileType = file.name
                    .substring(file.name.lastIndexOf(".") + 1)
                    .toLowerCase();

                const extension = fileType === "jpg";
                const extension1 = fileType === "jpeg";
                const extension2 = fileType === "gif";
                const extension3 = fileType === "psd";
                const extension4 = fileType === "png";
                if (
                    !extension &&
                    !extension1 &&
                    !extension2 &&
                    !extension3 &&
                    !extension4
                ) {
                    setTimeout(async () => {
                        await this.$message({
                            customClass: 'upload-tip',
                            type: "error",
                            message: "上传的图片只支持jpg、jpeg、png、gif、psd格式的图片 ",
                        })
                    })
                    return reject(false)

                }

                const randomNum = new Date().getTime() + "" + parseInt(Math.random() * 1000)
                reqQiniuToken()
                    .then(response => {
                        const token = response.data.data.token;
                        const hz = file.name.substring(file.name.lastIndexOf(".") + 1) //图片后缀
                        this.uploadDataObj.token = token;

                        this.uploadDataObj.key = randomNum + "." + hz
                        this.domainUrl = response.data.data.domain
                        resolve(true);
                    })
                    .catch(err => {
                        file.progressFlag = false
                        file.progressPercent = 0
                        reject(false)
                    })

            })

        },
        // 文件超出个数时
        onExceedHandle (files, fileList) {
            this.$message({
                type: 'error',
                message: '最多只能上传10张图片'
            })
        },
        // 文件上传失败
        onErrorHandle (err, file, fileList) {
            file.progressFlag = false
            file.progressPercent = 0
            this.$message({
                type: 'error',
                message: `"${file.name}"的照片,上传失败`
            })

        },
        // 文件上传成功
        onSuccessHandle (response, file, fileList) {
            this.fileList = fileList
            this.$emit('fileList', fileList)
            if (file.progressPercent === 100) {
                file.progressFlag = false
            }
            this.$message({
                type: 'success',
                message: `已成功上传"${file.name}"的照片`
            })
        },
        // 文件上传中
        onProgressHandle (event, file, fileList) {
            file.progressFlag = true
            file.progressPercent = parseInt(event.percent)
            if (file.progressPercent >= 100) {
                file.progressPercent = 100
            }
        },
        submitUpload () {
            this.$refs.upload.submit();
        },
        clearFilesHandle () {
            this.$refs.upload.clearFiles();
            this.fileList = [];
        },
        abortFiles (file) {
            this.$refs.upload.abort(file);
        },
    }
}
</script>

样式

<style lang="scss" scoped>
.del-img {
    position: absolute;
    top: -7px;
    right: -6px;
    z-index: 999;
    font-size: 28px;
    cursor: pointer;
    color: #fb1b1b;
    width: 24px;
    height: 24px;
    background: #fff;
    border-radius: 50%;
    line-height: initial;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-pack: center;
    -ms-flex-pack: center;
    justify-content: center;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
}
.kh-upload {
    /deep/ .el-upload-list__item {
        transition: none !important;
    }
    /deep/ .el-upload-list--picture-card .el-upload-list__item {
        overflow: inherit;
    }
    /deep/ .el-upload-list--picture-card {
        display: contents;
    }
}
</style>
<style lang="scss">
.upload-tip {
    &.el-message.is-closable {
        .el-message__content {
            padding-right: 25px;
        }
    }
}
</style>

eventBus.js代码

import Vue from 'vue'
export default new Vue()