nest上传图片
前端使用react+antd的upload
效果
import React, { memo, useState, useEffect } from "react";
import { Upload as AntdUpload, message } from "antd";
import { LoadingOutlined, PlusOutlined } from "@ant-design/icons";import "./Upload.style.scss";
import { UploadChangeParam } from "antd/lib/upload";
import { RcFile, UploadFile } from "antd/lib/upload/interface";function getBase64(img: any, callback: any) {const reader = new FileReader();reader.addEventListener("load", () => callback(reader.result));reader.readAsDataURL(img);
}function beforeUpload1(file: any) {const isJpgOrPng &#61; file.type &#61;&#61;&#61; "image/jpeg" || file.type &#61;&#61;&#61; "image/png";if (!isJpgOrPng) {message.error("You can only upload JPG/PNG file!");}const isLt2M &#61; file.size / 1024 / 1024 < 2;if (!isLt2M) {message.error("Image must smaller than 2MB!");}return isJpgOrPng && isLt2M;
}interface Props {onChange?: (imgUrl: string) &#61;> void;beforeUpload?: (file: any) &#61;> boolean;value?: string;[k: string]: any;
}export const Upload: React.FC<Props> &#61; memo(({ onChange, value, beforeUpload &#61; beforeUpload1, ...otherProps }: Props) &#61;> {const [loading, setLoading] &#61; useState(false);const [img, setImg] &#61; useState("");const uploadButton &#61; (<div>{loading ? <LoadingOutlined /> : <PlusOutlined />}<div style&#61;{{ marginTop: 8 }}>Upload</div></div>);useEffect(() &#61;> {if (value) {setImg(value);}}, [value]);const handleChange &#61; (info: any) &#61;> {if (info.file.status &#61;&#61;&#61; "uploading") {setLoading(true);return;}if (info.file.status &#61;&#61;&#61; "done") {getBase64(info.file.originFileObj, () &#61;> {setImg(info.file.response.url);onChange && onChange(info.file.response.url);});}};return (<div className&#61;{"upload"}><AntdUploadname&#61;"file"listType&#61;"picture-card"showUploadList&#61;{false}action&#61;"http://localhost:5000/upload"beforeUpload&#61;{beforeUpload}onChange&#61;{handleChange}{...otherProps}>{img ? (<img src&#61;{img} alt&#61;"avatar" style&#61;{{ width: "100%" }} />) : (uploadButton)}</AntdUpload></div>);}
);
这个handleChange使处理后台返回来的值&#xff0c;我们约定后台的是一个包含文件类型的值&#xff0c;就可以通过状态来判断是否成功&#xff0c;做出对应的操作。
这里是在formItem完成的&#xff0c;所以要实现两个value,和一个onChange
定义内部图片状态&#xff0c;上传后先显示
外部value改变时再改变该状态
formitem需要执行一个valuePropName的名字为value,而trigger用于设置收集字段值变更的时机。由onChange事件的发生来收集value&#xff0c;这样就相当于一个普通的formItem了。
后台实现&#xff1a;
由于我们使用nest并且基于exprss框架的&#xff0c;所以我们使用一个库来完成&#xff0c;有点类似于express的multer。
在主模块中使用import来注册&#xff0c;里面可以配置路劲&#xff0c;还有文件名。
看看express的配置
有点类似&#xff0c;都是配置storage&#xff0c;然后注册。这样上传的文件就会到达uploads文件夹里了。
我们上传到uploads文件夹后&#xff0c;需要返回改路劲给前端
我们在控制器中定义一个接口&#xff0c;处理文件&#xff0c;图中的api是nest提供的&#xff0c;可以获取到上传文件的file。此时的file已经通过处理并且上传到uploads了&#xff0c;所以可以通过file.filename拿到路劲。最后返回该文件即可。
静态资源开放
我们返回文件的路劲之后还要开放静态资源&#xff0c;不然前端访问不到&#xff0c;
也是基于express&#xff0c;所以使用同一个库&#xff0c;将其uploads的资源开放出来。这样前端就能正常访问了。
效果如开头那样