zoukankan      html  css  js  c++  java
  • vue中的文件上传和下载

    文件上传

    vue中的文件上传主要分为两步:前台获取到文件和提交到后台

    获取文件

    前台获取文件,主要是采用input框来实现

    <el-dialog :title="addName" :visible.sync="dialogAddFile" width="500px" style="padding:0;" @close="resetAdd">
                   附件名称:<el-input v-model="addFileName" autocomplete="off" size="small" style=" 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">支持扩展名:.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框实现文件上传;然后通过设置multiple="multiplt"实现了多文件上传,并且使用accept实现了上传文件类型限制;最后通过监听change事件,前台获取到上传的文件。

     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就能获取到上传的文件了,在上面再次对获取的文件进行了类型限制。

    数据提交

     获取到文件数据后,就需要将数据提交到后台,这里可以采用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: '附件上传成功!'
                        });
                    }
                })
            }

    在进行数据提交的时候,有两点需要注意:formData对象和Content-Type,处理好着两点以后,就和其他的接口一样了。

    文件下载

    首先是从服务器获取文件列表,并展示:

    <div class="about-file">
        <div class="about-file-title">相关材料</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>

    然后完成点击下载事件:

    toxiazai(index,num,id){
              var tempForm = document.createElement("form");//创建form表单,以下数form表单的各种参数
              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端,有很多文件都试采用下载的方式,但是在手机端,更多的是直接在线打开。如果要实现文件的在线打开,可以借助于a标签的href属性实现

    <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]">{{item.file_name}}</a>
             </div>
             <div class="person-list-time">上传时间:{{item.create_time}}</div>
         </li>
    </ul>

    因为使用这种方式进行文件打开的时候,需要有完整的路径名称,但是在从后台获取到列表的时候,通常是相对路径,所以需要进行路径拼接: v-bind:href="[filePrefix+item.uuid_name]"

    图片上传和预览

    通过在上传文件以后,就可以拿到文件的名称进行展示。但是如果是用这种方式进行图片上传,展示不再是图片名称了,而应该是图片展示。

    例如,要实现上面这种效果,使用input进行图片上传

    <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{
    
                    }
                }
            },

    因为在打印event对象的时候,发现上传的图片中包含一个path字段,对应的就是图片在设备上地址,就想当然的以为可以用这种方式展示图片,结果很显然的报错了,在网上查了一下才知道,要展示使用input上传的图片,需要使用FileReader。

    具体的就是,input获取到的图片,是不能立即展示的,两者根本不是一回事,所以,还需要一个数组,用来存放展示的图片。

    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);
                    }
                }
            },

    这样,提交数据的时候,使用的是imgArr,而展示的时候,使用的是imgShow

    还有一点需要注意的是,这里还有一个删除操作,这里的删除,不仅是在界面上的不可见,更是代表删除的这种照片,不需要传递到后台,因此,两个数组都需要进行删除

  • 相关阅读:
    int (*p)[10] 与*p[10]的区别
    运算顺序
    关于linux开机进入grub问题的解决方法
    对于特殊字符串的处理方法
    学习进度条
    阅读《实例化需求》4-6章有感
    学习进度条
    阅读《实例化需求》1-3章有感
    问题账户需求分析
    2016年秋季个人阅读计划
  • 原文地址:https://www.cnblogs.com/yuyujuan/p/10867557.html
Copyright © 2011-2022 走看看