手写antd提示组件
1. 功能需求
支持成功和提示类型的消息展示,可以连续弹出,并隔2秒消失。
2. 代码实现
jsx
import './JKMessage.css'
import { InfoCircleFilled, CheckCircleFilled } from '@ant-design/icons'
import { createRoot } from 'react-dom/client'
import PropTypes from 'prop-types'
function JKMessage({ msg = '', icon = null }) {
return (
<div className="jk-ant-message-notice">
<div className="jk-ant-message-notice-content">{icon} {msg}</div>
</div>
)
}
const jkMessage = {
wrapper: null,
root: null,
list: [],
showAndHide(msg, icon) {
// 有root需要提前卸载
if (this.root) {
this.root.unmount()
this.root = null
}
// 创建消息挂载DOM位置
if (!this.wrapper) {
this.wrapper = document.createElement('div')
this.wrapper.className = 'jk-ant-message'
document.body.appendChild(this.wrapper)
}
if (!this.root) {
// root不能多次创建,否则会报错
this.root = createRoot(this.wrapper)
this.list.push(
<JKMessage key={this.list.length} msg={msg} icon={icon} />
)
this.root.render(this.list)
}
setTimeout(() => {
// 一个一个消息挨个清除
this.list.shift()
this.root = null
this.wrapper.children[0].remove()
// 如果wrapper里面已经清除完毕所有消息,就清楚wrapper
if (this.list.length === 0) {
this.wrapper.remove()
this.wrapper = null
}
}, 2000)
},
info(msg) {
this.showAndHide(msg, <InfoCircleFilled style={{ color: 'blue' }} />)
},
success(msg) {
this.showAndHide(msg, <CheckCircleFilled style={{ color: 'green' }} />)
}
}
JKMessage.propTypes = {
msg: PropTypes.string,
icon: PropTypes.element
}
export default jkMessage
css
.jk-ant-message {
box-sizing: border-box;
margin: 0;
padding: 0;
color: rgba(0, 0, 0, 0.88);
font-size: 14px;
line-height: 1.5714285714285714;
list-style: none;
font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,'Helvetica Neue',Arial,'Noto Sans',sans-serif,'Apple Color Emoji','Segoe UI Emoji','Segoe UI Symbol','Noto Color Emoji';
position: fixed;
top: 8px;
width: 100%;
pointer-events: none;
z-index: 1010;
left: 50%;
transform: translateX(-50%);
top: 8px;
}
.jk-ant-message-notice {
padding: 8px;
text-align: center;
}
.jk-ant-message-notice-content {
display: inline-block;
padding: 9px 12px;
background: #ffffff;
border-radius: 8px;
box-shadow: 0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
pointer-events: all;
}
js
import JKButton from './JKButton/JKButton.jsx'
import JKRate from './JKRate/JKRate.jsx'
import jkMessage from './JKMessage/JKMessage.jsx'
export {JKButton, JKRate, jkMessage}
jsx
import { Button, message, Space } from 'antd'
import {jkMessage} from './JKAntd'
function App() {
const handleClick1 = () => {
message.info('hello Antd! ')
}
const handleClick2 = () => {
message.success("操作成功!")
}
const handleClick3 = () => {
jkMessage.info('hello Antd! ')
}
const handleClick4 = () => {
jkMessage.success("操作成功!")
}
return (
<>
hello App
<br />
<br />
<Space>
<Button type="primary" onClick={handleClick1}>点击1</Button>
<Button type="primary" onClick={handleClick2}>点击2</Button>
</Space>
<br />
<br />
<Space>
<Button type="primary" onClick={handleClick3}>点击1</Button>
<Button type="primary" onClick={handleClick4}>点击2</Button>
</Space>
</>
)
}
export default App
运行效果: