????????element-ui官網(wǎng)中有文件上傳
????????首先先展示一下我頁面的實現(xiàn)效果,如下圖所示:
?????????從圖中可以看出,我這邊實現(xiàn)的是一個可顯示進度條的文件上傳操作,而且如果上傳的文件很大等,還可以中斷文件上傳。
??????? 值得注意的是,如果有添加進度條,那就會存在一個bug,在文件沒上傳完時在點擊重新上傳文件進度條及百分比就會不停閃,原因是上個上傳請求在同時進行。
??????? 當然這些代碼也會在接下來的講解中進行解決
??????? 【解決方法】只需要在下圖位置操作時中斷請求即可
??????? 1.在彈框點擊取消和右上角X的時候中斷文件上傳請求
??????? 2.頁面上添加取消上傳按鈕,文件選擇按鈕點擊后,文件選擇按鈕置灰,直到文件上傳成功后才啟用?;蛘哂脩艨梢渣c擊取消上傳,此時中斷當前上傳請求,文件上傳按鈕啟用,用戶可以點擊按鈕繼續(xù)上傳文件
??????? 接下來看看代碼的大致結(jié)構(gòu):
??????? 1.頁面標簽和變量聲明
<el-row>
<el-col :span="8">
<el-form-item label="" prop="remark" label-width="105px">
<el-upload
ref="uploadFileList"
action=""
class="upload-demo"
style="display:inline-block;max-width: 670px;"
:limit="1"
multiple
list-type="text"
accept=".exe"
:before-upload="beforeUpload"
>
<el-button slot="trigger" size="small" type="primary" :disabled="fileBtnDisabled">選取文件</el-button>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="13">
<el-form-item label="" prop="fileName" label-width="0">
<el-input v-model="temp.fileName" maxlength="100" style="margin-top: 1px;" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-button style="margin-top: 2px;" size="mini" title="取消上傳" class="editBtn" @click="cancel1"><svg-icon icon-class="cancel" /></el-button>
</el-col>
</el-row>
<el-row v-if="progress">
<el-col :span="23">
<el-form-item label="" prop="" label-width="105px">
<el-progress
:percentage="progressPercent"
></el-progress>
</el-form-item>
</el-col>
</el-row>
progress: false, // 進度條是的顯示
progressPercent: 0, // 進度條百分比
source: null, // 中斷文件上傳請求用
fileBtnDisabled: false, // 文件上傳按鈕是否禁用
???????? 2.頁面方法實現(xiàn)
/**
* 文件上傳
* beforeupload阻止組件自動上傳,自己調(diào)上傳接口
* @param file
* @returns {boolean}
*/
beforeUpload(file) {
// console.log('file', file)
// 驗證
if (file.size === 0) {
this.$notify({
title: '失敗',
message: '不存在上傳文件',
type: 'error',
duration: 2000
})
return false
}
this.loading = true
const from = new FormData();
from.append('file', file);
from.append('type', 1);
this.progress = true // 顯示進度條
this.temp.fileName = '' // 文件名稱置空
this.progressPercent = 0 // 進度條百分比
const uploadEvent = (progressEvent) => { // 進度條百分比
this.progressPercent = Number(
((progressEvent.loaded / progressEvent.total) * 100).toFixed(2)
);
};
this.source = this.connectionSource() // 中斷請求時用
const cacheToken = this.source.token // 這個是上傳會話token,取消上傳操作需要的參數(shù)
this.fileBtnDisabled = true // 禁用上傳按鈕
/**
* 上傳文件接口
*/
fileUploading(from, uploadEvent, cacheToken).then(res => {
// 請求成功后,將文件名稱,路徑,大小復(fù)制到temp對應(yīng)字段中,新增修改要用
this.temp = Object.assign({}, this.temp, {
fileName: res.data.fileName,
url: res.data.url,
size: res.data.size
})
this.$notify({
title: '成功',
message: '請求成功',
type: 'success',
duration: 2000
})
this.progress = false // 隱藏進度條
this.loading = false
this.fileBtnDisabled = false // 啟用上傳按鈕
}).catch(() => {
this.progress = false // 隱藏進度條
this.loading = false
this.fileBtnDisabled = false // 啟用上傳按鈕
})
return false
},
/**
* 得到取消操作需要的連接
* */
connectionSource() {
return axios.CancelToken.source()
},
/**
* 彈框取消按鈕或右上方X點擊關(guān)閉彈框時,取消上傳
* 寫兩個取消上傳的原因是,如果取消上傳按鈕直接調(diào)這個方法,dialog彈框會關(guān)閉
* */
cancel() { // 取消上傳
this.dialogVisible = false
if (this.source) {
this.source.cancel()
this.fileBtnDisabled = false
}
},
/**
* 取消上傳按鈕
* */
cancel1() { // 取消上傳
if (this.source) {
this.source.cancel()
this.fileBtnDisabled = false
}
},
??????? 3.dialog彈框關(guān)閉時,中斷文件上傳
<el-dialog
v-el-drag-dialog
:close-on-click-modal="false"
:modal="false"
:title="title"
:visible.sync="dialogVisible"
width="600px"
@dragDialog="handleDrag"
@close="cancel"
>
</el-dialog>
<el-button @click="cancel">
取消
</el-button>
??????? 4.中斷請求還需要用到axios
import axios from 'axios' // 中斷文件上傳請求時使用
??????? 5.接口修改
/**
* 文件上傳
* (添加文件上傳進度條和中斷請求,對接口進行修改)
* @returns {AxiosPromise}
* type: 類型
*/
export function fileUploading(data, onUploadProgress, token) {
return request.post('/file/upload', data, { 'Content-Type': 'multipart/form-data', timeout: 0, onUploadProgress, cancelToken: token })
// return request({
// url: '/file/upload',
// method: 'post',
// data
// })
}
?經(jīng)過上面一系列操作后,文件上傳的功能就實現(xiàn)了,如果還有不清楚的話,我把edit.vue的代碼全部附上,但是真正文件上傳能用到的部分只有我上面代碼摳出來的部分。附上全部代碼只是為了方便大家查看具體一點的代碼結(jié)構(gòu)而已。
edit.vue完整代碼:文章來源:http://www.zghlxwxcb.cn/news/detail-454795.html
<template>
<div>
<el-dialog
v-el-drag-dialog
:close-on-click-modal="false"
:modal="false"
:title="title"
:visible.sync="dialogVisible"
width="600px"
@dragDialog="handleDrag"
@close="cancel"
>
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="right" label-width="75px" style="width: 550px;">
<el-row>
<el-col :span="23">
<el-form-item label="xx" prop="name" label-width="105px">
<el-input v-model="temp.name" maxlength="100"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="23">
<el-form-item label="xx" prop="fileType" label-width="105px">
<el-select v-model="temp.fileType" filterable placeholder="請選擇xx">
<el-option
v-for="item in fileTypeOption"
:key="item.id"
:label="item.label"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="" prop="remark" label-width="105px">
<el-upload
ref="uploadFileList"
action=""
class="upload-demo"
style="display:inline-block;max-width: 670px;"
:limit="1"
multiple
list-type="text"
accept=".exe"
:before-upload="beforeUpload"
>
<el-button slot="trigger" size="small" type="primary" :disabled="fileBtnDisabled">選取文件</el-button>
</el-upload>
</el-form-item>
</el-col>
<el-col :span="13">
<el-form-item label="" prop="fileName" label-width="0">
<el-input v-model="temp.fileName" maxlength="100" style="margin-top: 1px;" disabled></el-input>
</el-form-item>
</el-col>
<el-col :span="2">
<el-button style="margin-top: 2px;" size="mini" title="取消上傳" class="editBtn" @click="cancel1"><svg-icon icon-class="cancel" /></el-button>
</el-col>
</el-row>
<el-row v-if="progress">
<el-col :span="23">
<el-form-item label="" prop="" label-width="105px">
<el-progress
:percentage="progressPercent"
></el-progress>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="23">
<el-form-item label="xx" prop="version" label-width="105px">
<el-input v-model="temp.version" maxlength="100"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="23">
<el-form-item label="" prop="" label-width="105px">
<el-checkbox v-model="temp.isDeft">xx</el-checkbox>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="23">
<el-form-item label="xx" prop="remark" label-width="105px">
<el-input v-model="temp.remark" maxlength="100"></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="submitting" type="primary" @click="dialogStatus==='create'?createData():updateData()">
確認
</el-button>
<el-button @click="cancel">
取消
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import elDragDialog from '@/directive/el-dragDialog'
import { fileAdd, fileInfo, fileUpdate } from '@/api/systemOperational/softwareDownload';
import { fileUploading } from '@/api/file';
import axios from 'axios' // 中斷文件上傳請求時使用
export default {
name: 'Edit',
directives: { elDragDialog },
components: { },
props: {
title: {
type: String,
default() {
return ''
}
},
dialogStatus: {
type: String,
default() {
return ''
}
}
},
data() {
return {
progress: false, // 進度條是的顯示
progressPercent: 0, // 進度條百分比
source: null, // 中斷文件上傳請求用
fileBtnDisabled: false, // 文件上傳按鈕是否禁用
dialogVisible: false,
submitting: false,
temp: {},
defaultTemp: { // 表單字段
id: undefined,
name: '',
fileType: 1,
version: '',
fileName: '',
size: undefined,
isDeft: false,
remark: ''
},
fileTypeOption: [ // xx
{
id: 1,
label: 'xx'
}
],
rules: {
name: [
{ required: true, message: 'xx不能為空', trigger: 'blur' }
],
fileType: [
{ required: true, message: 'xx不能為空', trigger: 'blur' }
],
fileName: [
{ required: true, message: '請選擇文件', trigger: 'blur' }
],
version: [
{ required: true, message: 'xx不能為空', trigger: 'blur' }
]
}
}
},
computed: {
},
created() {
this.resetTemp()
},
methods: {
/**
* 文件上傳
* beforeupload阻止組件自動上傳,自己調(diào)上傳接口
* @param file
* @returns {boolean}
*/
beforeUpload(file) {
// console.log('file', file)
// 驗證
if (file.size === 0) {
this.$notify({
title: '失敗',
message: '不存在上傳文件',
type: 'error',
duration: 2000
})
return false
}
this.loading = true
const from = new FormData();
from.append('file', file);
from.append('type', 1);
this.progress = true // 顯示進度條
this.temp.fileName = '' // 文件名稱置空
this.progressPercent = 0 // 進度條百分比
const uploadEvent = (progressEvent) => { // 進度條百分比
this.progressPercent = Number(
((progressEvent.loaded / progressEvent.total) * 100).toFixed(2)
);
};
this.source = this.connectionSource() // 中斷請求時用
const cacheToken = this.source.token // 這個是上傳會話token,取消上傳操作需要的參數(shù)
this.fileBtnDisabled = true // 禁用上傳按鈕
/**
* 上傳文件接口
*/
fileUploading(from, uploadEvent, cacheToken).then(res => {
// 請求成功后,將文件名稱,路徑,大小復(fù)制到temp對應(yīng)字段中,新增修改要用
this.temp = Object.assign({}, this.temp, {
fileName: res.data.fileName,
url: res.data.url,
size: res.data.size
})
this.$notify({
title: '成功',
message: '請求成功',
type: 'success',
duration: 2000
})
this.progress = false // 隱藏進度條
this.loading = false
this.fileBtnDisabled = false // 啟用上傳按鈕
}).catch(() => {
this.progress = false // 隱藏進度條
this.loading = false
this.fileBtnDisabled = false // 啟用上傳按鈕
})
return false
},
/**
* 得到取消操作需要的連接
* */
connectionSource() {
return axios.CancelToken.source()
},
/**
* 彈框取消按鈕或右上方X點擊關(guān)閉彈框時,取消上傳
* 寫兩個取消上傳的原因是,如果取消上傳按鈕直接調(diào)這個方法,dialog彈框會關(guān)閉
* */
cancel() { // 取消上傳
this.dialogVisible = false
if (this.source) {
this.source.cancel()
this.fileBtnDisabled = false
}
},
/**
* 取消上傳按鈕
* */
cancel1() { // 取消上傳
if (this.source) {
this.source.cancel()
this.fileBtnDisabled = false
}
},
/**
* 打開新增彈框<父組件調(diào)用>
*/
handleCreateEditShow() {
this.resetTemp()
this.dialogVisible = true
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
/**
* 新增(確認)
*/
createData() {
this.submitting = true
this.$refs['dataForm'].validate((valid) => {
if (valid) {
const tempData = Object.assign({}, this.temp)
fileAdd(tempData).then(res => {
// console.log('res', JSON.parse(JSON.stringify(res)))
this.dialogVisible = false
this.$parent.refreshTab() // 子組件調(diào)用父組件方法,刷新列表
this.submitting = false
this.$notify({ title: this.$t('text.success'), message: '新增成功!', type: 'success', duration: 2000 })
}).catch(() => {
this.submitting = false
})
} else {
this.submitting = false
}
})
},
/**
* 打開修改彈框<父組件調(diào)用>
*/
handleUpdateEditShow(row) {
// console.log('row', JSON.parse(JSON.stringify(row)))
this.resetTemp()
this.dialogVisible = true
fileInfo({ id: row.id }).then(res => {
// console.log('詳情', JSON.parse(JSON.stringify(res)))
this.temp = res.data
})
this.$nextTick(() => {
this.$refs['dataForm'].clearValidate()
})
},
/**
* 修改(確認)
*/
updateData() {
this.submitting = true
this.$refs['dataForm'].validate((valid) => {
if (valid) {
const tempData = Object.assign({}, this.temp)
fileUpdate(tempData).then(res => {
// console.log('res', JSON.parse(JSON.stringify(res)))
this.dialogVisible = false
this.$parent.refreshTab() // 子組件調(diào)用父組件刷新表方法
this.submitting = false
this.$notify({ title: this.$t('text.success'), message: '修改成功!', type: 'success', duration: 2000 })
}).catch(() => {
this.submitting = false
})
} else {
this.submitting = false
}
})
},
hide() {
this.resetTemp()
this.dialogVisible = false
},
resetTemp() {
this.submitting = false
this.temp = { ... this.defaultTemp }
},
handleDrag() {
}
}
}
</script>
<style lang="scss" scoped>
>>>.el-checkbox{
margin-right: 19px;
}
>>>.el-progress-bar{
width: 97%;
}
</style>
好了,到此就結(jié)束了,希望這篇文章能幫助到大家文章來源地址http://www.zghlxwxcb.cn/news/detail-454795.html
到了這里,關(guān)于element-ui文件上傳el-upload的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!