React封装的组件
高阶函数 ,封装context
javascript
import React, { Component, createContext } from "react";
export const Context = createContext();
export const ContextProvider = ({ context, children }) => {
return <Context.Provider value={context}>{children}</Context.Provider>;
};
export const getChildrenContext = contexts => RealComponent => {
return class extends Component {
render() {
return (
<Context.Consumer>
{context => {
// 将顶层的context分发到各层
let mapContext = {};
if (Array.isArray(contexts)) {
contexts.map(item => (mapContext[item] = context[item]));
} else {
mapContext = context;
}
return <RealComponent {...mapContext} {...this.props} />;
}}
</Context.Consumer>
);
}
};
};封装的裁剪功能 带压缩下载
javascript
import React, { Component, Fragment } from "react";
import lrz from "lrz";
import { Upload, message, Button, Icon, Modal } from "antd";
import Cropper from "react-cropper";
import "cropperjs/dist/cropper.css";
import "./index.less";
class cropper extends Component {
state = {
srcCropper: "", //cropper的图片路径
selectImgName: "", //文件名称
selectImgSize: "", //文件大小
selectImgSuffix: "", //文件类型
editImageModalVisible: false, //打开控制裁剪弹窗的变量,为true即弹窗
imgData: [],
loading: false,
download: "",
};
downLoadImg = () => {
// this.refs.cropper.getCroppedCanvas({maxWidth: 4096, maxHeight: 4096});
this.setState({
download: this.refs.cropper
.getCroppedCanvas({
maxWidth: 4096,
maxHeight: 4096,
})
.toDataURL(),
});
};
saveImg = async () => {
const { loading } = this.state;
if (loading) return; //防止重复提交
this.setState({
loading: true,
});
// lrz压缩
// this.refs.cropper.getCroppedCanvas().toDataURL() 为裁剪框的base64的值
const { base64, base64Len } = await lrz(this.refs.cropper.getCroppedCanvas().toDataURL(), { quality: 0.6 });
const { imgData } = this.state;
imgData.push(base64);
this.setState(
{
imgData,
loading: false,
},
() => {
this.handleCancel();
}
);
// console.log(base64, base64Len / 1024);
};
beforeUpload = file => {
const isLt10M = file.size / 1024 / 1024 >= 10;
// console.log(file.size / 1024 / 1024);
if (isLt10M) {
//添加文件限制
message.error({ content: "文件大小不能超过10M" });
return;
}
let reader = new FileReader();
reader.readAsDataURL(file); //开始读取文件
// 因为读取文件需要时间,所以要在回调函数中使用读取的结果
reader.onload = e => {
this.setState({
srcCropper: e.target.result,
selectImgName: file.name,
selectImgSize: file.size / 1024 / 1024,
selectImgSuffix: file.type.split("/")[1],
editImageModalVisible: true,
});
};
reader.onerror = e => {
new Error("图片加载失败");
};
return false;
};
handleCancel = () => {
this.setState({
editImageModalVisible: false,
});
};
render() {
const { ratio, title } = this.props;
const { srcCropper, editImageModalVisible, imgData, loading, download } = this.state;
const props = {
name: "file",
accept: "image/*", //文件类型
showUploadList: false, //不以默认的列表显示
beforeUpload: this.beforeUpload, //阻止自动上传
onCancel: this.handleCancel,
};
return (
<Fragment>
<Upload {...props}>
<Button htmlType={"button"} type="dashed">
<Icon type="upload" />
{title}
</Button>
</Upload>
<Modal
title="裁剪"
visible={editImageModalVisible}
loading={true}
closable={false}
footer={[
<Button key={"取消"} icon={"redo"} htmlType={"button"} onClick={this.handleCancel}>
取消
</Button>,
<Button
key={"保存"}
icon={"save"}
htmlType={"button"}
type="primary"
onClick={this.saveImg}
loading={loading}
>
保存
</Button>,
<Button key={"下载"} htmlType={"button"} icon="download" type="primary" onClick={this.downLoadImg}>
<a href={download} style={{ color: "#fff", marginLeft: 5 }} download="cropped.jpg">
下载
</a>
</Button>,
]}
>
<Cropper
key={"cropper"}
ref="cropper"
src={srcCropper}
style={{ height: 300, width: "100%" }}
viewMode={1} //定义cropper的视图模式
zoomable={true} //是否允许放大图像
aspectRatio={ratio} //image的纵横比
guides={true} //显示在裁剪框上方的虚线
background={false} //是否显示背景的马赛克
rotatable={false} //是否旋转
/>
</Modal>
<div className={"imgBox"}>
{imgData.map((item, index) => {
return <img src={item} alt={item} key={index} />;
})}
</div>
</Fragment>
);
}
}
export default cropper;
cropper.defaultProps = {
ratio: 1,
src: "https://fengyuanchen.github.io/cropperjs/images/picture.jpg",
quality: 0.6,
title: "上传图片",
};