vue實(shí)現(xiàn)文件上傳和下載
本文實(shí)例為大家分享了vue實(shí)現(xiàn)文件上傳和下載的具體代碼,供大家參考,具體內(nèi)容如下
文件上傳
vue中的文件上傳主要分為兩步:前臺(tái)獲取到文件和提交到后臺(tái)
獲取文件
前臺(tái)獲取文件,主要是采用input框來實(shí)現(xiàn)
<el-dialog :title="addName" :visible.sync="dialogAddFile" width="500px" style="padding:0;" @close="resetAdd">
附件名稱:<el-input v-model="addFileName" autocomplete="off" size="small" style="width: 300px;" ></el-input>
<div class="add-file-right" style="height:70px;margin-left:100px;margin-top:15px;">
<div class="add-file-right-img" style="margin-left:70px;">上傳文件:</div>
<input type="file" ref="clearFile" @change="getFile($event)" multiple="multiplt" class="add-file-right-input" style="margin-left:70px;" accept=".docx,.doc,.pdf">
<span class="add-file-right-more">支持?jǐn)U展名:.doc .docx .pdf </span>
</div>
<div class="add-file-list">
<ul>
<li v-for="(item, index) in addArr" :key="index"><a >{{item.name}}</a></li>
</ul>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitAddFile" size="small">開始上傳</el-button>
<el-button @click="resetAdd" size="small">全部刪除</el-button>
</div>
</el-dialog>
最重要的是這一句代碼:

通過file類型的input框?qū)崿F(xiàn)文件上傳;然后通過設(shè)置multiple="multiplt"實(shí)現(xiàn)了多文件上傳,并且使用accept實(shí)現(xiàn)了上傳文件類型限制;最后通過監(jiān)聽change事件,前臺(tái)獲取到上傳的文件。
getFile(event){
var file = event.target.files;
for(var i = 0;i<file.length;i++){
// 上傳類型判斷
var imgName = file[i].name;
var idx = imgName.lastIndexOf(".");
if (idx != -1){
var ext = imgName.substr(idx+1).toUpperCase();
ext = ext.toLowerCase( );
if (ext!='pdf' && ext!='doc' && ext!='docx'){
}else{
this.addArr.push(file[i]);
}
}else{
}
}
},
通過change事件中的event.target.files就能獲取到上傳的文件了,在上面再次對獲取的文件進(jìn)行了類型限制。
數(shù)據(jù)提交
獲取到文件數(shù)據(jù)后,就需要將數(shù)據(jù)提交到后臺(tái),這里可以采用FormData的方式提交。
submitAddFile(){
if(0 == this.addArr.length){
this.$message({
type: 'info',
message: '請選擇要上傳的文件'
});
return;
}
var formData = new FormData();
formData.append('num', this.addType);
formData.append('linkId',this.addId);
formData.append('rfilename',this.addFileName);
for(var i=0;i<this.addArr.length;i++){
formData.append('fileUpload',this.addArr[i]);
}
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': this.token
}
};
this.axios.post(apidate.uploadEnclosure,formData,config)
.then((response) => {
if(response.data.info=="success"){this.$message({
type: 'success',
message: '附件上傳成功!'
});
}
})
}
在進(jìn)行數(shù)據(jù)提交的時(shí)候,有兩點(diǎn)需要注意:formData對象和Content-Type,處理好著兩點(diǎn)以后,就和其他的接口一樣了。
文件下載
首先是從服務(wù)器獲取文件列表,并展示:
<div class="about-file">
<div class="about-file-title">相關(guān)材料</div>
<ul>
<li v-for="(item, index) in tenEnclosure.rows" :key="index">
<a target="_self" >{{item.tenPencSourname}}</a>
<span @click="toxiazai(index,4,item.tenureId)" title="下載"></span>
<span @click="toshanchu(index,4,item.tenureId)" title="刪除"></span>
</li>
</ul>
</div>
然后完成點(diǎn)擊下載事件:
toxiazai(index,num,id){
var tempForm = document.createElement("form");//創(chuàng)建form表單,以下數(shù)form表單的各種參數(shù)
tempForm.id = "tempForm1";
tempForm.method = "post";
tempForm.action = apidate.downloadEnclosure;
tempForm.target="_";
var hideInput1 = document.createElement("input");
hideInput1.setAttribute('type','hidden');
hideInput1.setAttribute('name','linkId');
hideInput1.setAttribute('id','linkId');
hideInput1.setAttribute('value',id);
tempForm.appendChild(hideInput1);
var hideInput2 = document.createElement("input");
hideInput2.setAttribute('type','hidden');
hideInput2.setAttribute('name','num');
hideInput2.setAttribute('id','num');
hideInput2.setAttribute('value',num);
tempForm.appendChild(hideInput2);
if(document.all){
tempForm.attachEvent("onsubmit",function(){}); //IE
}else{
var subObj = tempForm.addEventListener("submit",function(){},false); //firefox
}
document.body.appendChild(tempForm);
if(document.all){
tempForm.fireEvent("onsubmit");
}else{
tempForm.dispatchEvent(new Event("submit"));
}
tempForm.submit();//提交POST請求
document.body.removeChild(tempForm);
},
文件在線打開
在PC端,有很多文件都試采用下載的方式,但是在手機(jī)端,更多的是直接在線打開。如果要實(shí)現(xiàn)文件的在線打開,可以借助于a標(biāo)簽的href屬性實(shí)現(xiàn)
<ul>
<li v-for="(item,index) in noticeList" v-bind:key="index" class="person-list" @click="notice(index)">
<div class="person-list-name">
<a v-bind:href="[filePrefix+item.uuid_name]" rel="external nofollow" rel="external nofollow" >{{item.file_name}}</a>
</div>
<div class="person-list-time">上傳時(shí)間:{{item.create_time}}</div>
</li>
</ul>
因?yàn)槭褂眠@種方式進(jìn)行文件打開的時(shí)候,需要有完整的路徑名稱,但是在從后臺(tái)獲取到列表的時(shí)候,通常是相對路徑,所以需要進(jìn)行路徑拼接: v-bind:href="[filePrefix+item.uuid_name]"
圖片上傳和預(yù)覽
通過在上傳文件以后,就可以拿到文件的名稱進(jìn)行展示。但是如果是用這種方式進(jìn)行圖片上傳,展示不再是圖片名稱了,而應(yīng)該是圖片展示。

例如,要實(shí)現(xiàn)上面這種效果,使用input進(jìn)行圖片上傳
<div class="list-img">
<ul>
<li v-for="(item,index) in imgArr" :key="index">
<img :src="item.path" alt="" >
<a @click="todel(index)"></a>
</li>
<li>
<div class="addImg" v-if="imgArr.length<3">
<span class="add">上傳圖片</span>
<span class="add">(最多上傳3張)</span>
<input type="file" @change="getFile($event)" accept=".jpg,.png,.bmp,.gif">
</div>
</li>
</ul>
</div>
getFile(event){
var file = event.target.files;
for(var i = 0;i<file.length;i++){
// 上傳類型判斷
var imgName = file[i].name;
var idx = imgName.lastIndexOf(".");
if (idx != -1){
var ext = imgName.substr(idx+1).toUpperCase();
ext = ext.toLowerCase( );
if (ext!='jpg' && ext!='png' && ext!='bmp' && ext!='gif'){
}else{
this.imgArr.push(file[i]);
}
}else{
}
}
},

因?yàn)樵诖蛴vent對象的時(shí)候,發(fā)現(xiàn)上傳的圖片中包含一個(gè)path字段,對應(yīng)的就是圖片在設(shè)備上地址,就想當(dāng)然的以為可以用這種方式展示圖片,結(jié)果很顯然的報(bào)錯(cuò)了,在網(wǎng)上查了一下才知道,要展示使用input上傳的圖片,需要使用FileReader。
具體的就是,input獲取到的圖片,是不能立即展示的,兩者根本不是一回事,所以,還需要一個(gè)數(shù)組,用來存放展示的圖片。
getFile(event){
var file = event.target.files;
let that = this;
for(var i = 0;i<file.length;i++){
// 上傳類型判斷
var imgName = file[i].name;
var idx = imgName.lastIndexOf(".");
if (idx != -1){
var ext = imgName.substr(idx+1).toUpperCase();
ext = ext.toLowerCase( );
if (ext!='jpg' && ext!='png' && ext!='bmp' && ext!='gif'){
}else{
that.imgArr.push(file[i]);
}
}else{
}
//展示上傳的圖片
let reader = new FileReader()
reader.readAsDataURL(file[i])
reader.onload = function(e) {
that.imgShow.push(this.result);
}
}
},
這樣,提交數(shù)據(jù)的時(shí)候,使用的是imgArr,而展示的時(shí)候,使用的是imgShow


還有一點(diǎn)需要注意的是,這里還有一個(gè)刪除操作,這里的刪除,不僅是在界面上的不可見,更是代表刪除的這種照片,不需要傳遞到后臺(tái),因此,兩個(gè)數(shù)組都需要進(jìn)行刪除

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
vue項(xiàng)目開發(fā)中setTimeout等定時(shí)器的管理問題
這篇文章主要介紹了vue項(xiàng)目開發(fā)中setTimeout等定時(shí)器的管理問題,需要的朋友可以參考下2018-09-09
Vue3實(shí)現(xiàn)轉(zhuǎn)盤抽獎(jiǎng)效果的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何通過Vue3實(shí)現(xiàn)簡單的轉(zhuǎn)盤抽獎(jiǎng)效果,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,感興趣的可以了解一下2023-10-10
Vue3+vite實(shí)現(xiàn)使用svg可改變顏色的全過程
Vue3 + Vite 使用 SVG 的方法主要是為了引入和利用圖標(biāo)庫、自定義組件以及通過插件簡化項(xiàng)目構(gòu)建過程,這篇文章給大家介紹了Vue3+vite實(shí)現(xiàn)使用svg可改變顏色的全過程,需要的朋友可以參考下2024-07-07
vue+el-table實(shí)現(xiàn)合并單元格
這篇文章主要為大家詳細(xì)介紹了vue+el-table實(shí)現(xiàn)合并單元格,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
使用vite創(chuàng)建vue3之vite.config.js的配置方式
這篇文章主要介紹了使用vite創(chuàng)建vue3之vite.config.js的配置方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
基于vue-cli 路由 實(shí)現(xiàn)類似tab切換效果(vue 2.0)
這篇文章主要介紹了基于vue-cli 路由 實(shí)現(xiàn)類似tab切換效果(vue 2.0),非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2019-05-05
Vue中代碼傳送(teleport)的實(shí)現(xiàn)
本文主要介紹了Vue中代碼傳送(teleport)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04

