vue+element UI 實現(xiàn)文件上傳
1、帶參數(shù)上傳文件
注意點:
參數(shù)通過屬性:data = ”params"傳遞,對象類型。
-
第一次上傳沒帶參數(shù),第二次上傳傳遞的是第一次的參數(shù)。解決方案:
在選擇文件的時候就設(shè)置好參數(shù),而不是在beforeupload的回調(diào)函數(shù)中設(shè)置。
手動上傳比較好,給upload 加一個ref
<el-upload
class="upload-area"
drag
:action="`/operation/org/member/data/upload`"
:on-error="handleError"
multiple
:data="uploadParams"
:auto-upload="false"
ref="uploadRef"
@click="handleBeforeUpload"
>
...
const uploadParams = reactive({
configId: '',
});
....
function handleBeforeUpload(): void {
uploadFormRef.value.validate().then(() => {
uploadParams.configId = uploadForm.configId;
});
}
...
function handleUpload(): void {
uploadFormRef.value.validate().then(() => {
uploadRef.value.submit();
closeDialog();
});
}
ps ?? elementui upload 上傳文件詳解
2、文件上傳之前先校驗文內(nèi)容規(guī)則是否符合預(yù)期,在提交,而且有圖標(biāo)顯示校驗效果。
由于上傳文件校驗和提交調(diào)用的接口雖然名稱不同,但是后端處理的邏輯是一樣的,前端選擇和處理的文件也是同一個,所以upload組件中的action 屬性的URL是不一樣的,如果點擊varify 或者submit 的時候改變使用計算屬性改變URL,實際并不好使用,因為使用了同一個上傳組件,提交的URL不一樣,但是成功的回調(diào)又是同一個,要針對兩種場景下的提交做判斷,通過點擊不同的按鈕實現(xiàn)并不科學(xué),因為可能對同一個按鈕點擊多次,那么何時改變URL變得難以監(jiān)聽。。。
最后解決方式是使用兩個upload 組件,除了對應(yīng)的action 對應(yīng)的URL不一樣之外,其他的都一樣就搞定了。。。(ps:一開始想到了這思路,但是覺的不應(yīng)該讓代碼復(fù)用率這么低——對同一個組件使用兩個upload組件,固執(zhí)的做各種判斷,最后代碼的魯棒性極差。。寫代碼還是需要靈活一點。。。。)
代碼如下:
<el-upload
:action="`/operation/upload/check`"
:auto-upload="false"
:on-preview="handlePreview"
:file-list="fileData"
ref="uploadRef"
:on-success="handleSuccess"
:on-error="handleError"
:on-change="handleChange"
:mutiple="false"
@click="handleSelect"
>
<el-button class="btn-select">Select</el-button>
</ks-upload>
<ks-upload
:action="`/operation/upload`"
:auto-upload="false"
:on-preview="handlePreview"
:file-list="fileData"
ref="submitRef"
:on-success="handleSuccess"
:on-error="handleError"
:on-change="handleChange"
:mutiple="false"
@click="handleSelect"
>
</el-upload>
<el-button v-if="hasFile" class="btn-verify" @click="onVerify"> Data Verify</el-button>
</div>
<!-- 顯示上傳的文件名 校驗錯誤圖標(biāo) 覆蓋自動上傳的fileList -->
<div v-if="showFile">
<span class="file"> {{ fileName }}</span> <i v-if="varifyErr" class="ks-icon-error"></i>
<i v-if="varifyPass" class="sys-icon-checkbox-circle-fill"></i
></div>
<!-- 展示上傳錯誤信息 -->
<div v-if="varifyErr" class="err-message">
<div v-for="errItem in errorMessage" :key="errItem.message">
{{ errItem.message }}
</div>
</div>
function onVerify(): void {
// 判斷當(dāng)前是校驗文件還是提交,接口路徑不同
isCheck.value = true;
uploadRef.value.submit();
// 點擊文件校驗時候會調(diào)用handleChange,如果校驗之前點擊過下載會導(dǎo)致圖標(biāo)無效。
clickFile.value = false;
}
function onSubmit(): void {
if (!varifyPass.value) {
Message.error('please verify the file coorectly!');
return;
}
// uploadRef.value.submit();
submitRef.value.submit(); // 不同的upload組件ref不同
closeDialog();
}
function handleSuccess(data: any, file: any, fileList: any): void {
fileList[0].status = 'ready'; // 校驗和提交使用的同一個文件,校驗之后還可以提交
if (data.result === 1) {
// 如果是文件校驗
if (isCheck.value) {
varifyErr.value = false;
varifyPass.value = true;
isCheck.value = false;
Message.success('Data Verify successfully');
} else {
Message.success('Submit successfully');
}
} else {
Message.error(data.message);
varifyErr.value = true;
varifyPass.value = false;
errorMessage.value = data.data;
}
}
// 點擊文件列表中已上傳的文件時的鉤子,可實現(xiàn)下載
function handlePreview(file?: any): void {
clickFile.value = true;
const URL = window.URL || window.webkitURL;
const fileURL = URL.createObjectURL(file.raw);
// window.open(fileURL); //直接下載,文件名是亂碼的
// 讓下載的文件名和上傳一樣
const name = file.name;
const a = document.createElement('a');
a.setAttribute('download', name);
a.setAttribute('target', '_blank');
a.setAttribute('href', fileURL);
a.click();
}