後臺玩前端,第一次使用VUE+Element。
對於文件上傳這一塊折騰了好久才搞定,記個筆記。同時幫助需要的人。
VUE代碼如下:
<el-upload
class="upload-demo"
ref="upload-demo"
action="http://localhost"
accept=".xlsx,.xls"
:limit="2"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-exceed="handleExceed"
:on-change="handleChange"
:file-list="fileList"
:before-upload="beforeUpload"
:before-remove="beforeRemove"
:http-request="doUpload"
:on-success="handleSuccess"
:on-error="handleError"
:auto-upload="false">
<el-button slot="trigger" size="small" type="primary">選取文件</el-button>
<el-button size="small" type="success" @click="submitUpload">上傳</el-button>
<div slot="tip" class="el-upload__tip">請選擇 Execl 文件,然後點擊上傳。</div>
</el-upload>
關鍵點:
- 由於自定義了上傳方法,因此 action 隨便填寫一個。原因參見第5點。
- accept 指定了可選的文件類型,讓OS幫你過濾掉不可選的文件。也可以不指定,推遲到before-upload()事件裏自己做文件的限定檢查。目錄下文件比較多的情況下,推薦指定。
- limit 限定選擇的文件個數,由於這裏只允許一個上傳一個文件,並支持更新所以設定2個。大於2也可以。
- file-list 用於存儲選擇的文件列表。通過變更可以實現列表的動態變化。這裏通過覆蓋寫實現選擇文件的更新。
- http-request 這個屬性是這裏的關鍵設置,它指定了自定義的上傳方法。如果沒有設定,那麼控件會使用 action 觸發上傳。
- on-success, on-error 實現自定義的上傳成功和失敗的回調。
腳本如下:
<script>
export default {
data () {
return {
fileList: [], //上傳的文件列表
}
},
methods: {
// 刪除選擇的文件時觸發
handleRemove (file, fileList) {
console.log(file, fileList)
},
// 點擊文件時觸發
handlePreview (file) {
console.log(file)
},
// 當選擇文件個數超過指定 limit 時觸發;這裏只上傳一個文件,指定了 limit="2",也可以不指定limit,則無限制
handleExceed (files, fileList) {
this.$message.warning(`已選擇了 ${files.length} 個文件,如需更新請先刪除已選擇文件`)
console.log(files)
},
//當重新選擇文件時,替換已選擇的文件,從而實現變更要上傳的文件,保證上傳列表中只有一個文件;limit要大於2,否則只會觸發onExceed,而不執行onChange
handleChange(files, fileList) {
this.fileList = [files]
},
//上傳成功的自定義callback
handleSuccess (response, file, fileList) {
//清空文件列表
this.$refs.uploadClass.clearFiles()
this.$message({
showClose: true,
message: '上傳成功',
type: 'success'
})
},
//上傳失敗的自定義callback
handleError (err, file, fileList) {
this.$message({
showClose: true,
message: file.name + ' 上傳失敗,' + JSON.stringify(err),
type: 'error'
})
},
//點擊刪除文件時觸發刪除確認提醒
beforeRemove (file, fileList) {
return this.$confirm(`確定移除 ${file.name}?`)
},
//上傳前的觸發,可以在這裏對文件大小,類型等檢測
beforeUpload (file) {
if (file.size > 1024 * 1024) {
this.$message.warning('上傳的文件大於1Mb,請靜心等待!')
}
},
//自定義上傳接口
doUpload (param) {
//上傳到騰訊雲cos,
cos.putObject({
Bucket: "",
Region: ""
Key: param.file.name,
StorageClass: 'STANDARD',
Body: param.file,
onProgress: function (progressData) {
//顯示上傳進度,採用百分制。
param.file.percent = progressData.percent * 100
//進度條
param.onProgress(param.file)
}
}, function (err, data) {
if (data && data.statusCode === 200) {
//callback我們自定義的handleSuccess
param.onSuccess(data)
} else {
//callback 我們自定義的handleError
param.onError(data)
}
})
//自己的post請求可以使用axios
/*this.axios({
method: 'post',
url: '服務地址',
data: param.file,
}).then(res => {
if (res.status === 200) {
}
}).catch(err => {
console.log(err)
})*/
},
//上傳
submitUpload () {
this.$refs.uploadDemo.submit()
},
}
</script>
重點說明
- 進度條的顯示一定要設定 param.file.percent 並執行 param.onProgress(param.file) 否則,進度條不顯示進度。
- 進度條的百分比使用的百分制。百分比可以使用file的參數計算得出。
摸石頭過河,總算跑起來了!
更多細節參看官方文檔 Element upload