多个文件上传的核心就是将文件append进FormData的实例中,向后台请求时将实例对象传送过去。
页面结构:
多个文件上传,传送的数据:
先上代码:
html部分:
<el-upload
class="upload-demo"
ref="upload"
action=""
:on-change="handleChange"
:on-remove="handleRemove"
:file-list="fileList"
:limit="3"
:on-exceed="handleExceed"
multiple
:auto-upload="false">
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">提交文件</el-button>
</el-upload>
js部分(this.$request是我自定义的请求方式,大家可以根据自身需要来调整):
data() {
return {
fileList: []
}
},
methods: {
// 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用
handleChange(file, fileList) {
// 对选中的文件做判断
if (file.raw.type !== 'text/plain') {
this.$refs.upload.handleRemove(file)
return
}
this.fileList = fileList
},
// 文件列表移除文件时的钩子
handleRemove(file, fileList) {
console.log('移除', file, fileList)
this.fileList = fileList
},
// 文件超出个数限制时的钩子
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
// 提交文件
submitUpload() {
if (this.fileList.length !== 0) {
const formData = new FormData()
this.fileList.forEach((item, index) => {
formData.append(`file${index + 1}`, item.raw)
console.log(item.raw, item)
})
// 后端上传接口
this.MultipartFile(formData).then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
} else {
this.$message({
message: '提交文件数量不可为空',
type: 'warning'
})
}
},
// 后端上传接口
MultipartFile(data) {
return this.$request({
url: 'https://jsonplaceholder.typicode.com/posts/',
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' }, // 多文件上传这一句必须加
data
})
},
}
解析:
1. 我们想要的效果是手动一次性上传多个文件,但是文件选取时,默认是自动上传的,所以要设置不立即上传
auto-upload | 是否在选取文件后立即进行上传 | boolean | — | true |
:auto-upload="false"
2. 由于我们想要上传多个文件,必须自定义网络请求中的一些内容,我们会在提交文件的时候手动发起网络请求,所以将action设置为"",或者也看到一些文章设置为 # ,
action | 必选参数,上传的地址 | string |
action=""
3. on-change 、 on-remove 和 on-exceed 钩子函数,我们要在on-change 、 on-remove钩子函数中存储文件到数组中,在 on-exceed 钩子函数中设置文件超出个数的处理,设置这个钩子函数时,要设置限制文件个数,使用 limit 字段
on-remove | 文件列表移除文件时的钩子 | function(file, fileList) |
on-change | 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用 | function(file, fileList) |
on-exceed | 文件超出个数限制时的钩子 | function(files, fileList) | — | - |
很重要的一个地方就是对不符合条件的文件进行移除,我们不但不让该文件存储在文件数组里,而且还要从upload中删除,不然的话,不符合条件的文件还是会在页面上显示的。例如,我们只想让文件类型为 text/plain的文件保存并显示在页面中,但是我们不对页面中显示的文件做手动的删除:
代码:
handleChange(file, fileList) {
console.log(file.raw.type)
if (file.raw.type !== 'text/plain') {
return
}
this.fileList = fileList
},
效果:不符合要求的docx结尾的文件也显示在了页面
所以,我们要手动的去删除upload中的不符合条件的文件,核心代码:
if (file.raw.type !== 'text/plain') {
this.$refs.upload.handleRemove(file)
return
}
效果(只有txt文件出现在页面上):
总的html部分:
:on-change="handleChange"
:on-remove="handleRemove"
:limit="3"
:on-exceed="handleExceed"
js部分:
handleChange(file, fileList) {
// 对选中的文件做判断
if (file.raw.type !== 'text/plain') {
this.$refs.upload.handleRemove(file)
return
}
this.fileList = fileList
},
handleRemove(file, fileList) {
console.log('移除', file, fileList)
this.fileList = fileList
},
handleExceed(files, fileList) {
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
},
4. 提交文件
触发提交文件函数后,可以先设置文件提交的一些要求,我设置的是有文件才能提交。。。
文件的提交要使用 FormData 构造函数来new一个实例,然后将文件数组中的文件都append到实例对象里边
const formData = new FormData()
this.fileList.forEach(item => {
formData.append('files', item.raw)
console.log(item.raw, item)
})
append('请求接口时的参数','数据')
5. 接下来就是调用接口传输数据了,一般向后端传输数据都是用的post,这里很重要的就是设置请求头。
this.$request({
url: 'https://jsonplaceholder.typicode.com/posts/',
method: 'post',
headers: { 'Content-Type': 'multipart/form-data' }, // 多文件上传这一句必须加
data: 'form实例'
})
差不多就是这样了,有什么错误,留言改正。