背景
最近在用 react 做移动端的时候需要一个消息提示的组件,然后我们的 ui 库是用的 MATERIAL-UI ,然后发现 antd-moblie Toast 不错。虽然可以用antd mobile 的组件并且只需要配置按需加载并不会增大多少打包体积,但是总感觉下一个库就用一个组件有点浪费,所以决定自己造个轮子
成品
rmc-notification
我把 antd-moblie 下载完以后阅读他的源代码,发现他是依赖了一个 rc 系列的一个库 rmc-notification。接下来干啥呢
npm instsall
发现报错了缺少 rc-animate,继续 npm i rc-animate --save
运行
运行起来以后基础组件长这样
先不管丑不丑看看直接看 api 好不好用
基础版
文档写的简单,功能也简单
var Notification = require('rmc-notification');
Notification.newInstance({}, notification => {
notification.notice({
content: 'content'
});
});
升级版
官方的例子解锁更多的姿势
import 'rmc-notification/assets/index.css';
import Notification from 'rmc-notification';
import React from 'react';
import ReactDOM from 'react-dom';
let notification = null;
Notification.newInstance({}, (n) => notification = n);
function simpleFn() {
notification.notice({
content: <span>simple show</span>,
onClose() {
console.log('simple close');
},
});
}
function durationFn() {
notification.notice({
content: <span>can not close...</span>,
duration: null,
});
}
function closableFn() {
notification.notice({
content: <span>closable</span>,
duration: null,
onClose() {
console.log('closable close');
},
closable: true,
});
}
function close(key) {
notification.removeNotice(key);
}
function manualClose() {
const key = Date.now();
notification.notice({
content: <div>
<p>click below button to close</p>
<button onClick={close.bind(null, key)}>close</button>
</div>,
key,
duration: null,
});
}
看完以后发现满足自己的功能了我们先改造起来
美化
设计
- 普通提示
- 成功提示
- 失败提示
- loaing
- 配置
封装
先写一个基础类
class Toast {
duration = 2;
loadingText = '努力加载中';
config(c) {
}
info(tip, duration) {
}
success(tip, duration) {
}
fail(tip, duration) {
}
loading(loadingText) {
}
hide() {
}
然后开始填充基础的代码, loading 比较特殊最好考虑
class Toast {
duration = 2;
loadingText = '努力加载中';
config(c) {
this.duration = c.duration;
this.loadingText = c.loadingText;
}
info(tip, duration) {
notification.notice({
content: <div className="toast_body">{tip}</div>,
duration,
});
}
success(tip, duration) {
notification.notice({
content: (
<div className="toast_body">
<CheckIcon className="toast_success" />
<div className="toast_tip">{tip}</div>
</div>
),
duration: duration || this.duration,
});
}
fail(tip, duration) {
notification.notice({
content: (
<div className="toast_body">
<FailIcon className="toast_success" />
<div className="toast_tip">{tip}</div>
</div>
),
duration: duration || this.duration,
});
}
loading(loadingText) {
}
hide() {
}
}
loading
loading 比较特殊的原因是因为它的场景和其他的不一样,其他的是几秒内就消失了。loading 他要等待请求结束才消失,而 rmc-notification 提供的让 Toast 消失的 api是要有一个唯一key, 所以我们这么写
loading(loadingText) {
const key = Date.now();
this.key = key;
notification.notice({
content: (
<div className="toast_body">
<LoadingIcon className="toast_loading" spin rotate={90} />
<div className="toast_tip">{loadingText || this.loadingText}</div>
</div>
),
duration: null,
key,
});
}
hide() {
notification.removeNotice(this.key);
}
css 部分
.rmc-notification-notice {
background: rgba(58, 58, 58, 0.9);
padding: 7px 10px;
}
.rmc-notification-notice-content {
color: #fff !important;
font-family: "Roboto", "Helvetica", "Arial", sans-serif;
font-size: 0.875rem;
font-weight: 200;
}
.toast_success {
font-weight: 200;
font-size: 2.25rem;
display: block;
}
.toast_body {
display: flex;
flex-direction: column;
align-items: center;
}
.toast_loading {
font-size: 2.25rem;
width: 2.25rem;
height: 2.25rem;
display: inline-block;
-webkit-transform: rotate(360deg);
-moz-animation: rotation 1s linear infinite;
-webkit-animation: rotation 1s linear infinite;
-o-animation: rotation 1s linear infinite;
}
.toast_tip {
margin-top: 0.375rem;
}
@-webkit-keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
最后
到这里就已经满足基础需求了,还有更多的功能就需要自己加了,当然我的代码也有很多优化空间,不过本文的目的是安利 rmc-notification 这个库,毕竟 REACT 不像 VUE那么多组件库。ღ( ´・ᴗ・` )比心