天天看点

vue结合element-ui得上传文件

需求:用vue框架,结合element-ui进行本地文件得上传,同时对文件需要MD5

界面如下:

vue结合element-ui得上传文件

标题

同时如果截止时间到了后,需要置灰对应的按钮:发布按钮、导入按钮、删除按钮

html:

就是element-ui得上传组件

auto-upload:true自动上传

beforeUpload:上传之前把对应的文件得信息以及参数拼接好

disabled:截至时间后置灰导入按钮

其他参数没怎么用

<el-upload
              class="upload-file"
              action="/ignore/"
              :before-upload="beforeUpload"
              ref="newupload"
              multiple
              :auto-upload="true"
              :disabled="isGrey"
            >
              <el-button type="text" plain :disabled="isGrey">导入</el-button>
            </el-upload>
           

js:因为要用md5以及一些分块,所以安装了browser-md5-file

import BMF from 'browser-md5-file';//先安装,再引用
const bmf = new BMF();
           
methods:{
    /* 上传文件之前得处理   */
beforeUpload(file){
  console.log('当前的文件信息',file)
  this.timestamp = new Date().getTime();//当前时间时间戳
  //策略文件类型
  const rzrk = ['rzrk'];
  const notebook = ['ipynb'];
  const Image = ['image/png'];
  const start = file&&file.name.lastIndexOf('.');
  const fileType = file.name.substr(start+1).toLowerCase();
  const isExistRzrk = rzrk.includes(fileType)
  const isImage = Image.includes(file.type)
  const index = 0;
  //上传的地址,和后台协商
  let  url =  '/upload_attachment/'
   bmf.md5(file,(err,md5)=>{
     //上传需要用到的一些参数,和后台协商
    this.uploadInfo = {
      chunks:Math.ceil(file.size/this.pack_size),//分块
      md5: md5,
      index:index,
      file:file.slice(index*this.pack_size,(index+1)*this.pack_size),
      fileName:file.name,
      per_size:this.pack_size,
      content_type: file.type,
      time_stamp: this.timestamp,
      string_stamp: this.timestamp,
      is_image_type:isImage ?1:0,
      normal_file:isExistRzrk?1:0
    }
     if (isExistRzrk) {
       this.commonFile(url,file,'rzrk')
     }
     else if(notebook.includes(fileType)){
       this.commonFile(url,file,'notebook')
     }
     else  {
       this.commonFile(url,file,'local')
     }
  })
},
/* 参数append进formdata里
* state:区别是本地还是策略还是notebook文件
*/
commonFile(url,file,state){
  let formdata = new FormData();
  const keys = Object.keys(this.uploadInfo)
  if (keys) {//上传用得是formdata,把参数放进去
    keys.forEach(item=>{
      return formdata.append(item,this.uploadInfo[item])
    })
  }
  this.uploadAttachment(formdata,url,file,state)
},
/** 
上传附件
 * state:区别是本地还是策略还是notebook文件
 * file:文件流信息
 * **/
uploadAttachment(formdata,url,file,state){
  let config = {
    headers:{'Content-Type':"multipart/form-data"}
  }
  axios.post(url,formdata,config).then(({data})=>{
    if(data.success == 1){
      let json ={
        content_type: file.type,
        file_id: data.file_id,
        file_name: file.name
      }
      !this.newFileList.includes(json)&&this.newFileList.push(json);//所有上传的文件数组
//分文件类型保存
      if (state=='local') {
        !this.local_file_ids.includes(data.file_id)&&this.local_file_ids.push(data.file_id);
      }
      else if (state=='notebook'){
        !this.notebook_file_ids.includes(data.file_id)&&this.notebook_file_ids.push(data.file_id);
      }
      else if (state=='rzrk') {
        !this.strategy_file_ids.includes(data.file_id)&&this.strategy_file_ids.push(data.file_id);
      }
      this.$message('发布成功');
    }else{
      this.$message(data.error);
    }
  })
},
}
           

自此,文件上传结束,文件得预览、下载要和后台协商,文件删除也要请求告诉后台

补充:下面是上传成功后再次从后台请求回文件名,进行表格展示,同时可以预览、下载、删除(其他功能都可以添加)

ps:element-ui也有文件的删除,也可以自己在上传组件基础上添加这些功能,这里需要把自动上传改为手动上传

html:附件部分用的table,所以可以拿到每行得index以及数据

<el-table ref="multipleTable" :data="fileList" tooltip-effect="dark" style="width: 100%" v-if="fileList.length!=0">
<!--                <el-table-column type="selection" ></el-table-column>-->
                <el-table-column prop="file_name"  > </el-table-column>
                <el-table-column >
                      <template slot-scope="scope">
                        <el-button @click="previewFile(scope.row,0,scope.$index)" type="text" size="small">查看</el-button>
                        <a class="download_file" @click="downloadFile(scope.row,1,scope.$index)" >下载</a>
                        <el-button @click="deleteFile(scope.row,scope.$index)" type="text" size="small" :disabled="isGrey">删除</el-button>
                      </template>
                </el-table-column>
              </el-table>
           

文件删除功能:我这里和后台商量的是,文件上传成功后,后台会返回一个文件的id给前端,然后前端保存下来,前端要展示文件的时候,就把这些id传给后台,后台把文件名等信息传给前端进行展示(其他思路可以商量)

/**
 * 作业提交部分的文件删除
 *
 * **/
deleteFile(row,index){
  let json = {
    file_ids:JSON.stringify([row.file_id])
  }

  APIService.deleteAttachment(json).then(res=>{
    if (res.success==1){
      this.warnTip('删除成功','success')
      //筛选新得附件列表,被删除得附件不再显示,当然也可以重新获取附件列表
      this.newFileList = this.newFileList.filter(item=>{
        return item!=row
      })
    }
    else{
      this.warnTip(res.error,'warning')
    }
  })
    .catch(error=>{
      //this.warnTip(error,'warning')
      console.log('error请求失败',error)
    })
},
           

文件下载和查看功能:这里合后台商量的思路是:前端把当前要预览或者下载的文件的id传给后台,因为共用的一个网址,所以区分预览和下载又加了一个参数判断,(这里的下载是一个a标签,然后给a标签href属性动态赋值,预览就是打开另一个窗口)

/** 下载本地文件 和notebook
 * row: 某行文件数据
 * state:下载为1,预览为0
 * index: 索引
 * **/
downloadFile(row,state,index){
  this.isPreviewOrDownload(row,state,index)
},
/** 预览某个文件
 * row: 某行文件数据
 * state:预览为0,下载为1
 * index: 索引
 * */
previewFile(row,state,index) {
  this.isPreviewOrDownload(row,state,index)
},
/**
 * 文件预览和下载的逻辑  
 * **/
isPreviewOrDownload(row,state,index){
  //需要什么参数和后台商量
  const src = `/download_attachment/?file_id=${row.file_id}&download=${state}`;
  if (state==1) {//下载
    document.getElementsByClassName('download_file')[index].setAttribute('href',src)
  }
  else{
    const origin = window.location.origin;

    window.open(origin + src);
  }
},
           

以上是文件得上传,单个文件得预览、下载和删除功能,欢迎交流

继续阅读