自定义element UI的upload组件

  • 2019 年 11 月 20 日
  • 筆記

简介

ElementUI中的upload组件使用固然很简便,但是我们可能有更复杂的应用。

比如要开发一个手写数字识别的前端,上传到的服务器的是一张手写数字的图片,返回识别的结果,这个应用无法直接由upload组件实现。

当然,我们也可以先上传,维护一个图片的token,然后后台根据这个token去取相应的数据。但这样不仅要维护一个token,还要和文件系统(磁盘)交互,要考虑上传到哪里、如何删除等问题。不如直接传递方便。

实现

自定义上传函数

绑定http-request到自定义函数即可

<el-upload    class="upload-demo"    :http-request="uploadSectionFile"    ref="upload"    action=""    :on-preview="handlePreview"    :on-remove="handleRemove"    :before-remove="beforeRemove"    :limit="1"    :on-exceed="handleExceed"    :auto-upload="false"    :file-list="fileList">    <el-button   type="primary" icon="el-icon-upload">点击上传</el-button>    <div slot="tip" class="el-upload__tip">只能上传wav文件,且不超过500kb</div>  </el-upload>

该函数只有一个参数param, 并且param.file就是我们要上传的文件对象。

function uploadSectionFile(param){      var fileObj = param.file      var form = new FormData()      form.append("file", fileObj)      // other code ....  }

实现上传进度条

上传用axios实现,进度条由axios和uploadSectionFile的param参数配合实现。

param.file.percentparam.onProjress用来显示进度条。

let config = {        onUploadProgress: progressEvent => {            var complete = (progressEvent.loaded / progressEvent.total * 100 | 0)            param.file.percent = complete            param.onProgress(param.file)        },        headers: {            'Content-Type': 'multipart/form-data'          }        }

实现上传成功状态

依旧是param参数。

param.onSuccess('文件上传成功')

完整代码

vue

<template>    <div class="home">      <h1>Hello</h1>      <el-row>        <el-col :span="8">        <el-upload          class="upload-demo"          :http-request="uploadSectionFile"          ref="upload"          action=""          :on-preview="handlePreview"          :on-remove="handleRemove"          :before-remove="beforeRemove"          :limit="1"          :on-exceed="handleExceed"          :auto-upload="false"          :file-list="fileList">          <el-button   type="primary" icon="el-icon-upload">点击上传</el-button>          <div slot="tip" class="el-upload__tip">只能上传wav文件,且不超过500kb</div>        </el-upload>        </el-col>        <el-col :span="8">          <el-button type="primary" @click="handleButton('upload-model')" icon="el-icon-upload">加载模型</el-button>        </el-col>        <el-col :span="8">          <el-button type="primary" @click="handleButton('begin-analyse')" icon="el-icon-video-play">开始分析</el-button>        </el-col>      </el-row>      <el-row>      <el-col :span="12">        <div class="row-softmax">          <h2>模型原始输出</h2>            <el-table              :data="softmax_output"              :max-height = "330"              border              style="width: 100%">              <el-table-column                prop="label"                label="标签"                width="148">              </el-table-column>              <el-table-column                prop="probability"                label="概率"                width="148">              </el-table-column>            </el-table>        </div>      </el-col>        <el-col :span="12">        <el-row>          <el-col :span="24">            <div class="time-frequency">            <img class="base64Img" :src="time_frequency_pic_base64">            </div>          </el-col>        </el-row>        <el-row>          <el-col :span="24">            <div class="final-result">            <h2>归类</h2>            <p>  final_result }} </p>            </div>          </el-col>        </el-row>        <el-row>          <el-col :span="24">            <div class="save-result">            <el-button type="primary"><i class="el-icon-upload el-icon--right"></i>保存结果</el-button>            </div>          </el-col>        </el-row>      </el-col>      </el-row>    </div>  </template>  <script>  import { predict } from '@/api/tensorflow'  export default {    name: 'HelloWorld',    data () {      return {        fileList: [],        fileObj: '',        time_frequency_pic_base64:'',        readable_labels: [],        final_result: '',        softmax_output: [          {            'label' : '类别1',            'probability' : 0.1          },          {            'label' : '类别1',            'probability' : 0.1          },          {            'label' : '类别1',            'probability' : 0.1          },          {            'label' : '类别1',            'probability' : 0.1          },          {            'label' : '类别1',            'probability' : 0.1          }        ]      }    },    methods: {      handleRemove(file, fileList) {        console.log(file, fileList);      },      handlePreview(file) {        console.log(file);      },      handleExceed(files, fileList) {        this.$message.warning(`当前限制选择 1 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);      },      beforeRemove(file, fileList) {        return this.$confirm(`确定移除 ${ file.name }?`);      },      uploadSectionFile(param){        console.log(param)      let config = {        onUploadProgress: progressEvent => {            var complete = (progressEvent.loaded / progressEvent.total * 100 | 0)            param.file.percent = complete            param.onProgress(param.file)        },        headers: {            'Content-Type': 'multipart/form-data'          }        }        var fileObj = param.file        var form = new FormData()        form.append("file", fileObj)        predict(form, config)        .then( (data) => {          console.log(data)          this.time_frequency_pic_base64 = 'data:image/jpg;base64,' + data.data.time_frequency_pic_base64          this.final_result = data.data.final_result          this.softmax_output = data.data.softmax_output          param.onSuccess('文件上传成功')        })      },      handleButton(type){         if(type == 'upload-model'){           console.log('Not implement yet. Upload model')         }         else if(type == 'begin-analyse'){           console.log('Begin anaylyse')           this.$refs.upload.submit()         }      },      handleChange(type){        if(type == 'file'){          this.fileObj = document.getElementById("upfile").files[0]        }else if(type == 'model'){        }      }    }  }  </script>

axios

import axios from 'axios'  export function predict(data, config) {    return axios.post('your_address',data,config)  }