背景玩前端,第一次使用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