“This is my seventh day of the November Gwen Challenge.The final text challenge in 2021” |
---|
I recently had a task to write an upload page, which is a background page, so I preferred to use
in Element-UI.
Since fragment upload is required, we define the upload event HTTP-Request, but when we check with the background, we find that the progress bar in the file-list is not…. , it just happens that the effect picture provided by UI is a little different from that provided by Upload, so please customize it.
1. Part of the page code
- Hide the default file-list list
- Declare a custom upload event
http-request
<el-upload
class="upload-demo"
ref="upload"
action="/"
multiple // Multiple file uploads
:action="uploadUrl" // File upload address (required)
:show-file-list="false" // Custom styles so set false not to display
:file-list="fileArr"// List of files
:http-request="checkedFile" // Customize the upload event
:before-upload="beforeUploadFile" // Before uploading the file
:on-progress="uploadFileProcess" // File transfer process (processing progress bar)
:on-success="handleFileSuccess" // File succeeded >
<el-button size="small" type="primary"</el-button> </el-upload>Copy the code
2. Part of js code
// Format the file size to display text
getSize(size) {
return size > 1024
? size / 1024 > 1024
? size / (1024 * 1024) > 1024
? (size / (1024 * 1024 * 1024)).toFixed(2) + 'GB'
: (size / (1024 * 1024)).toFixed(2) + 'MB'
: (size / 1024).toFixed(2) + 'KB'
: size.toFixed(2) + 'B'
},
async checkedFile(options) {
const { maxSize, multiUploadSize, getSize, splitUpload, singleUpload } =
this
const { file, onProgress, onSuccess, onError } = options
console.log('options', options, this)
if (file.size > maxSize) {
return this.$message({
message: 'The file you selected is greater than${getSize(maxSize)}`.type: 'error'})},// Upload slices larger than the specified size
const uploadFunc = file.size > multiUploadSize
? splitUpload
: singleUpload
try {
let info = await uploadFunc(file, onProgress)
this.$message({
message: info.msg || 'Upload successful'.type: 'success',
})
onSuccess()
} catch (e) {
console.error('error', e)
onError()
}
const prom = new Promise((resolve, reject) = > {})
prom.abort = () = > {}
return prom
},
// Upload large files in chunks
splitUpload(file, onProgress) {
return new Promise(async (resolve, reject) => {
try {
const { eachSize } = this
const chunks = Math.ceil(file.size / eachSize)
const fileChunks = await this.splitFile(file, eachSize, chunks)
let currentChunk = 1
let cbRes = []
for (let i = 1; i <= fileChunks.length; i++) {
CurrentChunk = currentChunk = currentChunk = currentChunk = currentChunk = currentChunk
console.log('before', currentChunk, i)
if (currentChunk === i) {
// After each block is uploaded, the index of the next block to be submitted is returned
let postRes = await this.postFile(
{
// chunked: true,
chunk: i,
chunks,
// eachSize,
name: file.name,
totalSize: file.size,
// uid: file.uid,
model: this.model,
file: fileChunks[i - 1],
},
onProgress
)
// Determine whether to continue according to the actual interface format
let status = postRes.key
if (status === 'continue') {
currentChunk = postRes.value
} else if (status === 'hasValue') {
currentChunk = postRes.value + 1
} else if (status === 'success') {
currentChunk = postRes.value
cbRes = postRes
} else {
currentChunk = postRes.value
}
console.log('after currentChunk', currentChunk)
}
}
resolve(cbRes)
} catch (e) {
reject(e)
}
})
},
// Split the file into blocks using array.prototype. slice
splitFile(file, eachSize, chunks) {
return new Promise((resolve, reject) = > {
try {
setTimeout(() = > {
const fileChunk = []
for (let chunk = 0; chunks > 0; chunks--) {
fileChunk.push(file.slice(chunk, chunk + eachSize))
chunk += eachSize
}
resolve(fileChunk)
}, 0)}catch (e) {
console.error(e)
reject(new Error('File chunking error'))}})},// Submit the file method, convert the parameters to FormData, and then make the request through AXIOS
postFile(param, onProgress) {
const formData = new FormData()
for (let p in param) {
formData.append(p, param[p])
}
const { requestCancelQueue } = this
const config = {
cancelToken: new axios.CancelToken(function executor(cancel) {
if (requestCancelQueue[param.uid]) {
requestCancelQueue[param.uid]()
delete requestCancelQueue[param.uid]
}
requestCancelQueue[param.uid] = cancel
}),
onUploadProgress: (e) = > {
console.log('onUploadProgress', e, param, this)
if (param.chunked) {
e.percent = Number(
(
((param.chunk * (param.eachSize - 1) + e.loaded) /
param.fullSize) *
100
).toFixed(2))}else {
e.percent = Number(((e.loaded / e.total) * 100).toFixed(2))
}
onProgress(e)
},
}
// Actual upload event
if (this.fileType === 0) {
return uploadStructTree(formData, config).then((rs) = > rs)
} else if (this.fileType === 2) {
return uploadTheory(formData, config).then((rs) = > rs)
} else if (this.fileType === 3) {
return uploadDmo(formData, config).then((rs) = > rs)
} else {
return upload3DToBos(formData, config).then((rs) = > rs)
}
},
Copy the code