因业务需求,需要用户自定义个人头像(图片剪切上传);调研了之后,决定使用react-cropper插件来实现头像上传功能!
react-cropper插件还是很全面不错的, 满足了功能的需要。
步骤实现:
1、安装
npm install --save react-cropper
2、文件引入
import "cropperjs/dist/cropper.css"
import Cropper from 'react-cropper'
3、render结构
render() {
return (
{this.cropper = cropper}}
/>
this.uploadImg()} />
)
}
备注: [1]、uploadCrop 指类名为 uploadCrop 的div作为预览窗口(如果无法预览, 需要添加样式:overflow:hidden)
[2]、src : 目标图片url
[3]、属性 accept:表示可以上传的文件类型,image表示图片,*表示所有的支持格式。(不建议使用accept属性,可使用JS验证或服务端验证)
4、核心代码
[1]、当input type=file 选取文件时, 对文件的类型和大小进行验证;
[2]、将 files[0] 的值传进来,读取,读取完成之后设置src,给下一步使用;
const FILE_TYPES = ["image/jpg", "image/png", "image/jpeg", "image/bmp"];
constructor(props) {
super(props);
this.state = {
src: null,
fileName: "newFile.jpeg"
}
this.onChange = this.onChange.bind(this);
}
onChange(e) {
e.preventDefault();
let files;
if(e.dataTransfer) {
files = e.dataTransfer.files;
} else if(e.target) {
files = e.target.files;
}
if(files.length > 0){
// 验证 files[0] 信息的文件大小
const fileMaxSize = 1024;
let fileSize = files[0].size/1024;
if(fileSize > fileMaxSize){
alert("文件不能大于1M!");
return false;
} else if(fileSize <= 0) {
alert("文件不能为0");
return false;
}
// 验证 files 信息的文件类型
const fileType = file.type;
if(!FILE_TYPES.includes(fileType)) {
alert("不接受此文件类型");
return false;
}
const reader = new FileReader();
reader.onload = () => {
this.setState({
src: reader.result
})
}
reader.readAsDataURL(files);
} else {
if(this.state.src === null) {
alert("请选择文件");
}
return false;
}
}
5、提交裁剪好的图片(form形式提交)
uploadImg() {
if(this.state.src === null) {
alert("请选择图片");
return false;
}
const croppedCanvas = this.cropper.getCroppedCanvas({
minWidth: 200,
minHeight: 200,
width: 200,
height: 200,
maxWidth: 200,
maxHeight: 200
});
if(typeof croppedCanvas === "undefined") {
return;
}
croppedCanvas.toBlob(async blob => {
// 图片name添加到blob对象里
blob.name = this.state.fileName;
// 创建提交表单数据对象
const filedata = new FormData();
// 添加要上传的文件
filedata.append('file', blob, blob.name);
try {
// 接口
let res = await upload(filedata, token);
if(res.errCode === 0) {
// 上传成功
} else {
// 上传失败
}
} catch(err) {
console.log(err);
}
}, "image/jpeg")
}
6、效果展示(至此,功能实现)
重要补充:
在第5步步骤中, 所使用到的upload方法, react中写的时候需要注意了, 不是传统的post能解决的,因为接收参数时,一个参数是body接收的form对象,一个是headers接收的token;代码如下:
upload(file, token) {
return fetch("url地址", {
body: file,
credentials: 'include',
headers: {
'token': token
},
method: 'POST'
})
.then(response => response.json())
}