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