el-upload使用避坑

3,354 阅读2分钟

el-upload主要用于文件上传

具体使用, template中:

<el-upload multiple action ref="refUpload" :headers="headers" :http-request="uploadFile" :file-list="fileList" :on-remove="handleRemove" :on-error="handleError" :before-remove="beforeRemove"
            :limit="20" :on-exceed="handleExceed" :before-upload="beforeUpload" show-file-list drag>
            <template #trigger>
                <el-button type="primary">点击上传文件</el-button>
            </template>
            <template #tip>
                <div class="el-upload__tip" style="margin-right: 80px">
                    可上传文件类型包括:pdf、doc、docx、jpg、png、jpeg
                </div>
                <div class="el-upload__tip" style="margin-right: 80px">
                    已上传{{ fileLength }}份简历
                </div>
            </template>
        </el-upload>

脚本文件:

import { ref, computed, reactive } from "vue";
import axios from "axios";
import { ElMessage, ElMessageBox, ElLoading } from "element-plus";
//文件目录
const fileList = reactive([])

const refUpload = ref(null)
const fileType = ["pdf", "doc", "docx", "png", "jpg", "jpeg"]

//文件个数
const fileLength = computed(() => {
    return fileList.length
})
const headers = reactive({
    'Content-Type': 'multipart/form-data'
})

// 上传文件
function uploadFile(item) {
    let formDatas = new FormData()
    formDatas.append('file', item.file)
    formDatas.append('fileId', item.file.uid)
    //上传文件
    return axios({
        method: 'post',
        url:xxx,
        headers,
        data: formDatas
    }).then(res => {
            fileList.push(item.file)
           
    })
}

//文件上传之前调用,用于判断文件类型和大小等
function beforeUpload(file) {
    let fileName = file.name
    if (file.type != "" || file.type != null || file.type != undefined) {
        //截取文件的后缀,判断文件类型
        const fileExt = file.name.replace(/.+\./, "").toLowerCase();
        console.log(fileExt)
        //计算文件的大小
         const isLt5M = file.size / 1024 / 1024 < 50; //这里做文件大小限制
         //如果大于50M
        if (!isLt5M) {
            this.$showMessage('上传文件大小不能超过 50MB!');
             return false;
         }
        //如果文件类型不在允许上传的范围内
        if (fileType.includes(fileExt)) {
            let found = fileList.find(file => file.name == fileName)
            if (found) {
                ElMessage({
                    type: 'error',
                    message: '该文件已上传!',
                    showClose: true
                })
                return false
            }
            return true;
        } else {
            ElMessage({
                message: `不能上传${fileExt}类型的文件`,
                type: 'error',
                showClose: true
            })
            return false;
        }
    }
}

function beforeRemove(file) {
    if (file && file.status == 'success') {
        return ElMessageBox.confirm('确认删除该文件吗?',
            'Warning',
            {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            })
    }
}

/**
 * 移除文件
 **/
function handleRemove(item) {
    if (item && item.status == 'success') {
        let uid = item.raw.uid
        axios.get(xxx, {
            params: {
                'fileId': uid
            }
        }).then(res => {
                let flag = 0
                fileList.some((item) => {
                    if (item.uid === uid) {
                        return
                    } else {
                        flag++
                    }
                })
                fileList.splice(flag, 1)
                ElMessage({
                    type: 'success',
                    message: '删除成功'
                })
        })
    }
}

function handleExceed() {
    ElMessage({
        type: 'error',
        message: '一次最多只能上传20个文件!',
        showClose: true
    })
}
}

主要属性和方法:

名称描述必填备注
action请求url如果不使用action可以设置action='#'或action
headers请求上传的头部传递formdata类型的数据,需要设置formdata的请求头
http-request覆盖默认的xhr行为可以在此自行实现文件的上传请求
file-list文件列表
limit限制的文件上传个数
multiple是否支持多选文件
drag是否启用拖拽上传
show-file-list是否显示已上传文件列表
before-upload上传文件之前的钩子,参数为上传的文件和文件列表如果返回false或者返回promise并且被reject,则停止上传
before-upload上传文件之前的钩子,参数为上传的文件和文件列表如果返回false或者返回promise并且被reject,则停止上传
on-exceed文件数超出限制时,执行的钩子函数
before-remove删除文件之前的钩子,参数为上传的文件和文件列表如果返回false或者返回promise并且被reject,则停止上传
on-remove文件列表移除文件时的钩子

此处遇到的一个问题:

  1. 需要在before-upload钩子函数中对文件类型和文件大小进行判断,不符合时会返回false,但是经过测试会发现如果直接返回false,会自动调用before-remove以及on-remove钩子函数,会产生错误。因此在这里,每次执行删除代码时都需要先判断文件是否上传成功,即判断文件的status,当status为success时才能执行删除的代码;
if (file && file.status == 'success') 
  1. 关于文件上传之后的状态:只有当上传文件的方法中返回true或者非reject形式的promise时才能将文件的status变更为success否则文件的状态将一直是ready。这时文件的后面会出现上传成功的标志对勾。

image.png