大家是怎么做的呢?
今天写了一个简单的 Toast 组件,贴出来,互相交流… 还有许多完善的地方
CSS NEXT
.toast {
position: fixed;
width: 320px;
padding: 1em 1.5em;
margin-left: -160px;
border-radius: var(--radius);
text-align: center;
color: #fff;
font-size: 14px;
}
.cancel {
position: absolute;
top: .25em;
right: .25em;
color: #fff;
cursor: pointer;
}
.center {
top: 50%;
left: 50%;
margin-top: -100px;
}
.top {
top: 80px;
left: 50%;
}
.right {
right: 20px;
top: 80px;
margin-left: 0;
}
.bottom {
bottom: 70px;
left: 50%;
}
.default {
background-color: color(#000 alpha(80%));
}
.success {
background-color: color(var(--success) alpha(90%));
}
.danger {
background-color: color(var(--failed) alpha(90%));
}
Javascript
/**
*
* Toast
*
*/
import React, { Component } from 'react'
import { v4 } from 'uuid'
import Cancel from 'react-icons/lib/md/cancel'
import styles from './styles.css'
let baseIndex = 12
class Toast extends Component {
constructor(props) {
super(props)
this.state = {
toasts: [],
zindex: baseIndex,
}
this._add = this._add.bind(this)
this._remove = this._remove.bind(this)
this._clearOnExpire = this._clearOnExpire.bind(this)
this._renderToasts = this._renderToasts.bind(this)
this._renderToastItem = this._renderToastItem.bind(this)
}
componentWillUnmount() {
const toasts = this.state.toasts
for (var i = 0; i < toasts.length; i++) {
clearTimeout(this[toasts[i].id])
}
}
_add(msg = '提示不能为空', {expire = 5000, type = 'default', position = 'top', style={}}) {
const zindex = this.state.zindex + 1
const message = {
id: v4(),
msg: msg,
type: type,
position: position,
zindex: zindex,
style: style,
expire: expire,
}
this.setState({
toasts: this.state.toasts.concat(message),
zindex: zindex,
}, () => this._clearOnExpire(message.id, expire))
return message.id
}
_remove(id) {
if(!this[id]) return
if(this.state.toasts.length === 1) {
this.setState({
zindex: baseIndex,
})
}
clearTimeout(this[id])
delete this[id]
this.setState({
toasts: this.state.toasts.filter((item) => item.id !== id)
})
}
_clearOnExpire(id, expire) {
this[id] = setTimeout(() => {
this._remove(id)
}, expire)
}
_renderToastItem(item, index) {
return (
<div
key={item.id}
style={{
...item.style,
zIndex: item.zindex
}}
className={`${styles.toast} ${styles[item.type]} ${styles[item.position]}`}
>
<Cancel
onClick={() => this._remove(item.id)}
className={styles.cancel}
/>
{item.msg}
</div>
)
}
_renderToasts() {
return this.state.toasts.map((item, index) => this._renderToastItem(item, index))
}
render() {
return (
<div>
{ this._renderToasts() }
</div>
)
}
}
export default Toast
只是简单的 toast ,展示思路…