天天看點

vue+express實作檔案上傳,顯示上傳進度條

1. 案例介紹

使用前後端分離開發的模式實作檔案上傳,前端使用Vue架構,後端使用node的express架構,并且顯示上傳進度條。

案例效果:

vue+express實作檔案上傳,顯示上傳進度條

2. 核心代碼

2.1 環境搭建

前端環境

# 安裝Vue腳手架
cnpm i -g @vue/cli

# 建立項目
vue create myapp

# 進入項目目錄
cd myapp

# 安裝axios
cnpm i axios --save

# 啟動項目
npm run serve
           

後端環境

# 安裝express腳手架
cnpm i -g express-generator

# 建立項目
express upload-demo

# 進入項目目錄
cd upload-demo

# 安裝multer子產品
cnpm i multer --save

# 啟動項目
npm start
           

因為要同時在本地啟動前端和後端的服務,是以把前端服務端口改成

8080

,後端服務端口改成

3000

2.2 前端核心代碼

建立檔案 views/Main.vue

<template>
	<div>
		<div>
			<input type="file" @change="fileSelect($event)" />
			<button @click="fileSubmit">上傳</button>
		</div>
		<div class="progress-wrap">
			<p>上傳進度</p>
			<p class="progress"><span :style="style"></span></p>
		</div>
	</div>
</template>

<script>
export default {
	data(){
		return {
			file: {}, //上傳的檔案對象
			progressBar: 0 // 記錄上傳進度的變量
		}
	},
	computed:{
		style(){ // 進度條樣式
			return {
				width: this.progressBar+"%"
			}
		}
	},
	methods:{
		fileSelect(e){ 
			this.file = e.target.files[0]
		},
		async fileSubmit(){
			const formData = new FormData();
			formData.append('file',this.file);
			await this.$axios.post('http://localhost:3000/file/upload',formData,{
				onUploadProgress: (progressEvent)=>{
				 var percentCompleted = Math.round( (progressEvent.loaded * 100) / progressEvent.total );
				 this.progressBar = percentCompleted
			}}).then(res=>{
				console.log(res.data)
			})
		}
	}
}
</script>

<style>
.progress-wrap {
	width: 300px;
}
.progress-wrap p {
	width: 100%;
}
.progress {
	background-color: #c5c8ce;
	height: 20px;
}
.progress span {
	display: block;
	background-color: #19be6b;
	height: 100%;
	width: 0;
}
</style>

           

2.3 後端核心代碼

建立路由檔案 routes/upload.js

let express = require('express')
let router = express.Router()
let multer = require('multer')
let fs = require('fs');
let path = require('path');

let upload = multer({
	storage: multer.diskStorage({
		//設定檔案存儲位置
		destination: function(req, file, cb) {
			let date = new Date();
			let year = date.getFullYear();
			let month = (date.getMonth() + 1).toString().padStart(2, '0');
			let day = date.getDate();
			let dir = "./uploads/" + year + month + day;

			//判斷目錄是否存在,沒有則建立
			if (!fs.existsSync(dir)) {
				fs.mkdirSync(dir, {
					recursive: true
				});
			}

			//dir就是上傳檔案存放的目錄
			cb(null, dir);
		},
		//設定檔案名稱
		filename: function(req, file, cb) {
			let fileName = file.fieldname + '-' + Date.now() + path.extname(file.originalname);
			//fileName就是上傳檔案的檔案名
			cb(null, fileName);
		}
	})
});

router.post('/upload', upload.single('file'), (req, res) => {
	res.json({
		file: req.file
	})
})

module.exports = router

           

post請求的中間件

upload.single('file')

中的參數要和前端

formData.append('file',this.file);

中的鍵名保持一緻。

2.4 上傳案例示範

分别啟動前端服務和後端服務,在浏覽器中通路前端服務位址:

http://localhost:8080

vue+express實作檔案上傳,顯示上傳進度條

繼續閱讀