自定義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.percent
和param.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) }