近期项目在使用Material-UI ,Material-UI 的消息提示组件是<Alert />,<Alert />没有主动提示的能力,属于被动组件,需要在页面中嵌入,然后通过属性open的true/false进行控制,在寻常的页面开发中使用到无大碍,但是不能运用到工具类的js中,如独立封装的axios;axios的独立分装意外要脱离页面,统一封装,拦截过滤。这个时候<Alert />就显得无能为力了,只能另行封装。
这里没有重新封装一个新的组件,而是使用Material-UI组件库中的Alert、Snackbar组合封装组件。
Snackbar API(只介绍需要用到的):
open: Boolean类型 true/false,控制消息框关闭
autoHideDuration:Number,控制显示时间
anchorOrigin: Object, 控制消息体显示位置
onClose: 主动关闭事件
Alert
ref
则会被传递到根元素中。
variant 'filled'
| 'outlined'
| 'standard'
| string
severity 'error'
| 'info'
| 'success'
| 'warning'
React.forwardRef: 引用传递(Ref forwading)是一种通过组件向子组件自动传递 引用ref 的技术。对于应用者的大多数组件来说没什么作用。但是对于有些重复使用的组件,可能有用
第一步:封装一个Message
function Message(props) {
const { content, duration, type } = {...props};
// 开关控制:默认true,调用时会直接打开
const [open, setOpen] = React.useState(true);
// 关闭消息提示
const handleClose = (event, reason) => {
setOpen(false);
};
return <Snackbar
open={open}
autoHideDuration={duration}
anchorOrigin={{ vertical: 'top', horizontal: 'center' }}
onClose={handleClose}>
<Alert severity={type}>{content}</Alert>
</Snackbar>
}
第二部: 引用Message,并定义message的主动事件
const message = {
dom: null,
success({content, duration}) {
// 创建一个dom
this.dom = document.createElement('div');
// 定义组件,
const JSXdom = (<Message content={content} duration={duration} type='success'></Message>);
// 渲染DOM
ReactDOM.render(JSXdom,this.dom)
// 置入到body节点下
document.body.appendChild(this.dom);
},
error({content, duration}) {
this.dom = document.createElement('div');
const JSXdom = (<Message content={content} duration={duration} type='error'></Message>);
ReactDOM.render(JSXdom,this.dom)
document.body.appendChild(this.dom);
},
warning({content, duration}) {
this.dom = document.createElement('div');
const JSXdom = (<Message content={content} duration={duration} type='warning'></Message>);
ReactDOM.render(JSXdom,this.dom)
document.body.appendChild(this.dom);
},
info({content, duration}) {
this.dom = document.createElement('div');
const JSXdom = (<Message content={content} duration={duration} type='warning'></Message>);
ReactDOM.render(JSXdom,this.dom)
document.body.appendChild(this.dom);
}
};
export default message;
从上述代码看思路很简单:第一步先决定提示消息的样式,有现成的用现成的组件组合;第二部,研究参数,把参数预置好,这里一些不会变化的参数值写死,变化的参数动态通过父组件传入即可;第三步,就是封装能力,根据不同的提示传入不同的参数,达到效果
引用如下:
if (status === 426 || status === 428 || status === 403) {
message.error({content: response.data.msg, duration: 2000})
}
if (status === 200) {
message.success({content: i18n.t('message.loaded'), duration: 1500})
}
if (status === 404) {
message.error({content: i18n.t('message.http404'), duration: 1500})
return null
}