一直以來,我都覺得上傳檔案的程式開發,是表單處理中的痛點,一般的<input type="file" />的功能比較簡略,介面不甚美觀。之前有發現 Uppy 這個套件,就對它感興趣,現在已經出了 1.0 版,想寫篇文章記錄一下心得。
這篇的文章的原始碼在這邊ngx-uppy-demo
npm install uppy
當執行 npm install uppy 時,是安裝 Uppy 的全部功能,這當然會使得安裝的檔案容量變大。
npm install @uppy/core @uppy/dashboard @uppy/xhr-upload
一般的作法,就是安裝所需的套件,如果想要使用 Dashboard,可以只安裝@uppy/dashboard 及@uppy/xhr-upload。
npm install @uppy/file-input @uppy/progress-bar @uppy/xhr-upload
如果只想要使用一般的 FileUpload,可以只安裝@uppy/file-input @uppy/progress-bar @uppy/xhr-upload
@Component({
selector: 'app-uppy',
templateUrl: './uppy.component.html',
styleUrls: ['./uppy.component.scss'],
})
export class UppyComponent implements AfterViewInit {
ngAfterViewInit(): void {
// Create Uppy object
}
}
因為擅長的是 Angular,所以這個範例,想將 Angular 和 Uppy 整合,所以首先實作 AfterViewInit,確認頁面的 DOM 都戴入完成後,才能建立 Uppy 的物件。
<div class="container">
<div class="uploadContainer"></div>
</div>
import * as Uppy from '@uppy/core';
import * as Dashboard from '@uppy/dashboard';
import * as XHRUpload from '@uppy/xhr-upload';
const uppy = Uppy({
autoProceed: true
});
uppy.use(Dashboard, {
inline: true,
target: '.uploadContainer'
});
uppy.use(XHRUpload, {
endpoint: '/api/file',
formData: true,
fieldName: 'fileData'
});
uppy.on('upload-success', (file, response: any) => {
this.imageDataService.add(response.body as ImageDatum);
});
使用 use 戴入所需的套件,這裡戴入 Dashboard 及 XHRUpload。
uppy.use(Dashboard, {
inline: true,
target: '.uploadContainer',
});
Dashboard 的參數可以參考官方文件。
uppy.use(XHRUpload, {
endpoint: '/api/file',
formData: true,
fieldName: 'fileData'
});
uppy.on('upload-success', (file, response: any) => {
this.imageDataService.add(response.body as ImageDatum);
});
XHRUpload 的參數可以參考文件,endpoint
指定 Server 端的 API 位置,並且是用監聽事件 upload-success 來判斷是否上傳成功。如此檔案或是圖片上傳的功能就完成。
Dashboard 的畫面如上,因為 Uppy 是上傳套件,無法戴入圖片,所以這邊有使用另一個套件ngx-gallery。
uppy
.use(FileInput, {
pretty: true,
target: '.uploadContainer',
inputName: 'fileData'
})
.use(Processbar, {
target: 'body',
fixed: true,
hideAfterFinish: true
l
});
uppy.use(XHRUpload, {
endpoint: '/api/file',
formData: true,
fieldName: 'fileData'
});
uppy.on('upload-success', (file, response: any) => {
this.imageDataService.add(response.body as ImageDatum);
});
程式碼與 Dashboard 的很相似,戴入 FileInput 的套件及設定參數,可以參考文件。
FileInput 的畫面如上。
import * as fileUpload from 'express-fileupload';
app.use(fileUpload());
Server 端是使用 express.js,而處理上傳檔案是用express-fileupload這個套件。
async handler(req: express.Request, res: express.Response) {
const { fileData } = req['files'];
const service = new FileService();
const fileRes = await service.upload(fileData);
return res.json(fileRes);
}
只需用 req.files.fileData 就可以存取到所上傳的物件,而 fileData 就是在XHRUpload套件上所設定 fieldName 的值。
Uppy 是目前我覺得很方便的上傳套件,簡單幾段程式就可以實作檔案上傳。