主要记录使用 upload 组件上传文件要显示上传进度条的问题
模版部分
// format 为支持的格式类型数组
const format = ['png', 'jpg', 'zip', 'txt', 'doc', 'docx', 'csv', 'xls', 'xlsx', 'mp3', 'mp4', 'pdf', 'rar', 'jpeg', 'ppt', 'm4a', 'mov']
<el-upload
ref="upload"
class="upload-file"
action={this.action}
accept={format.map(f => '.' + f.trim()).join(',')} // 转换成 accept 接受的数据格式
drag
multiple
before-upload={this.beforeUpload}
limit={5}
http-request={this.handleUpload}
file-list={this.fileList} // 文件列表,实际没啥用感觉,如果不是需求需要这个的话
// 第一个恶心的地方,upload的这些 on-xxx 的钩子函数对于函数式组件来说非常不友好
{...{props: {
'on-remove': (file, list) => this.onRemoveFile(file, list),
'on-exceed': () => {
this.$message({
message: '文件超出个数',
type: 'warning',
})
}
}}}
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">上传文案</div>
<div slot="tip" class="el-upload__tip" domPropsInnerHTML={'上传提示语'}></div>
</el-upload>
函数部分
handleUpload(e) {
/*
e 是上传的文件的一些信息和方法
如果只关心上传那就不需要写 promise,但是要在页面展示文件上传的状态就需要写promise 来抛出文件上传的一些状态
*/
const prom = new Promise((resolve, reject) => {
let args = {file: e.file}
args = this.$injectCancelToken(args, String(e.file.cancelToken)); // axios 配置的 CancelToken 用来中断请求
this.uploadLoading = true
this.uploadModel.fetch(args, {config: {
// axios 的请求配置;处理原生进度事件 // 浏览器专属
onUploadProgress: (progressEvent) => {
const { loaded, total } = progressEvent
// 计算百分比
const complete = parseInt(((loaded / total) * 100) | 0, 10)
// 调用 upload 的 onProgress方法 显示文件上传的进度条
e.onProgress({percent: complete})
}
}}).then(res => {
if(res.code === 10068) {
// 文件上传失败 调用 onError
e.onError()
return reject()
}
if(res.code === 200) {
this.$set(this.form.files, e.file.uid, res.data.file_path)
return resolve()
}
}).finally(() => {
this.uploadLoading = false
})
})
// !!!一定要写 abort,不然文件上传过程中取消上传会报错
prom.abort = () => {}
return prom
},
beforeUpload(file) {
const maxSize = 1024 * 1024 * 30
if(file.size > maxSize) {
this.$message.error('文件大小超出上传限制')
return false
}
// 在文件上传之前手动给file对象加上唯一标识 用于取消操作。实际不写也行,它文件会生成一个id 也是当前时间戳
const uniq = new Date().valueOf()
file.cancelToken = uniq
return true
},
onRemoveFile(file, list) {
let cancelToken = String(file.raw.cancelToken)
this.$cancelRequestByToken(cancelToken)
this.form.files[file.uid] = ''
}