upload组件运用以及修改使用
在开发一个后台管理平台的项目中遇到一个文件上传以及下载的需求,如下交互图所示
大致要完成这么一个功能,当然实际上需要考虑更多,这次主要是用了element 的组件,在加上自己稍加改造完成的。在组件里涉及到的方法基本都用到了。
先上一个结构代码
<el-dialog title="" :visible.sync="dialogFormVisible" @closed='closeDialog' :modal-append-to-body="false">
<el-upload
class="upload-demo"
style="text-align: center"
drag
ref="upload"
:headers="headers"
:before-upload="onBeforeUpload"
:auto-upload="false"
:on-change="changeFile"
:onError="uploadError"
:on-remove="removefile"
:onSuccess="uploadSuccess"
:limit="1"
accept=""
action="/gateway/device/deviceStockImport"
multiple>
<p><img src="../../assets/image/img/icon_inbox@3x.png" alt=""></p>
<div class="el-upload__text" style="font-size:0.16rem">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
<div class=result v-if=!check>
<p><img :src=Imgsrc alt=""></p>
<p>{{text_result}}</p>
<p>{{result_text}}</p>
<div v-if=sheet>失败原因:<span @click="downerr()"><a href="javascript:;">下载失败模板</a></span></div>
</div>
<div class="mould_text">
<p>请上传.xls格式的文件,点击此处</p>
<div @click=export_text() style="height: 0.16rem;line-height: 0.16rem">
<a style="color: #0fa8f5;cursor: pointer" herf="javascript:;">下载模版</a>
</div>
</div>
<div class="footer">
<el-button v-if=check type="primary" :disabled=isAble @click="upload()">开始上传</el-button>
<el-button v-if=check @click="cancel()">取 消</el-button>
<el-button type="primary" @click="cancel()" v-if=!check>{{text}}</el-button>
<el-button v-if=abolish @click="cancel1()">取 消</el-button>
</div>
</el-dialog>
- 文件上传成功情况
因为需要的是xls格式的文件,所以前端就可以做个判断,把不是xls格式的文件进行拦截不让上传。
//文件上传后判断是不是xls格式
onBeforeUpload(file) {
const extension2 = file.name.split('.')[1] === 'xls';
if (!extension2) {
document.querySelector('.el-upload-list--text').style.display = 'none';
this.text = '重新选择文件';
this.text_result = '文件上传失败';
this.check = false;
this.abolish = true;
this.sheet = false;
this.Imgsrc = require('@/assets/image/img/icon_close_circle@3x.png');
this.result_text = '请上传.xls格式的文件!';
}
return extension2;
}
// 文件选择成功后触发
changeFile(file) {
if (file.status == 'ready') {
document.querySelector('.el-upload--text').style.display = 'none';
document.querySelector('.mould_text').style.visibility = 'hidden';
document.querySelector('.el-upload-list--text').style.display = 'block';
this.isAble = false;
}
}
// 上传成功后的回调
uploadSuccess(response, file, fileList) {
if (response.data) {
document.querySelector('.el-upload-list--text').style.display = 'none';
this.text = '知道了'
this.text_result = '文件上传成功'
this.check = false;
this.Imgsrc = require('@/assets/image/img/icon_success_circle@3x.png');
this.taskId = response.data.taskId;
this.result_text = response.data.tips;
if (this.taskId) {
this.$parent.loading({}, 1, 10);
this.sheet = true;
} else {
this.sheet = false;
this.$parent.loading({}, 1, 10);
}
} else {
document.querySelector('.el-upload-list--text').style.display = 'none';
this.text = '重新选择文件'
this.check = false;
this.abolish = true;
this.sheet = false;
this.Imgsrc = require('@/assets/image/img/icon_close_circle@3x.png');
this.result_text = response.msg;
}
}
2、上传文件的时候可能需要下载一个文件模板所以这里也写了一个下载文件的方法
其主要就是调通接口获取文件流,利用了a标签的特性。
// 下载模板
export_text() {
this.axios.get(this.apiNames.device_download,
{
params: {
fileName: 'deviceStock'
},
headers: {
'content-type': 'application/vnd.ms-excel;charset=utf-8',
"token": this.$store.state.sessionId
},
responseType: "blob"
}
).then(
response => {
console.log(response.headers);
var blob = new Blob([response], {type: 'application/vnd.ms-excel;charset=utf-8'}); //指定格式为vnd.ms-excel
var downloadElement = document.createElement('a');
var href = window.URL.createObjectURL(blob); //创建下载的链接
downloadElement.href = href;
downloadElement.download = 'deviceStock.xls'; //下载后文件名
document.body.appendChild(downloadElement);
downloadElement.click(); //点击下载
document.body.removeChild(downloadElement); //下载完成移除元素
window.URL.revokeObjectURL(href); //释放掉blob对象
}
).catch(
err => {
this.$Message.error('文件下载失败,请稍后再试');
}
);
}
- 文件上传成功之后后台要对文件进行解析并将结果进行返回,这里用到的方法就是上面文件上传成功后的回调,这边分为三种情况,文件解析失败,文件解析成功并全部正确,文件解析成功并有部分错误
这里解析后如果有数据失败会返回失败的数据,直接文件下载跟下载模板一样。
大致就是这样,也不是很难,主要了解这个组件,知道触发的钩子函数就可以了,另外数据导入后在页面上会有个刷新直接用this.$parent调通父组件的数据加载方法就可以了。