实现目标
以react无状态组件方式实现一个消息弹发布到npm上使用
使用方式
在react中引入包
import rcAlert from 'rc-alert';
message.success(content, [duration], onClose)
message.error(content, [duration], onClose)
message.info(content, [duration], onClose)
message.warning(content, [duration], onClose)
message.warn(content, [duration], onClose)
复制代码
参数说明
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
content | 提示内容 | string/ReactNode | 无 |
duration | 自动关闭的延时,单位秒 | number | 3秒 |
onClose | 关闭时触发的回调函数 | Function | 无 |
具体实现
1. 实现方式:
第一次弹出消息时给的底部插入一个div,之后每次改变div里面的内容即可
2. 外层框架:
rcAlertMessage.newrcAlert()是生成消息框的函数,通过回调函数返回instance来判断是否已经生成外层框架
let rcAlertInstance = 0;
const className = 'myCat-rcAlert';
function outerFrame(callback) {
if (rcAlertInstance === 0) {
const div = document.createElement('div');
div.id = className;
document.body.appendChild(div);
rcAlertMessage.newrcAlert(className, function (instance) {
callback(instance);
rcAlertInstance = instance;
})
} else {
callback(rcAlertInstance);
}
}
复制代码
newrcAlert()函数:
App.newrcAlert = function (className, callback) {
function ref(app) {
callback({
notice(noticeProps) {
app.add(noticeProps);
app.onRemove(noticeProps);
},
})
}
let apps=new App();
let Apps=apps.render();
React.createElement('div', {ref: ref(apps)}, Apps,)
};
复制代码
3. 生成内容方式:
通过React.createElement()来创建函数,并以高阶函数的方式将内容创建以参数的方式传递给outerFram(callback),之后通过调取参数callback来实现内容的生成
outerFrame(function (instance) {
instance.notice({
key: key,
duration: duration,
style: {},
content: React.createElement(
'div',
{className: 'rcAlert-node-content'},
React.createElement(
'svg',
{className: `icon rcAlert-icon ${iconClass}`},
React.createElement(
'use', {xlinkHref: iconType}
),
),
React.createElement(
'span',
null,
content
)
),
onClose: callback
})
}
复制代码
4. 生成内容:
以构造函数的方式实现元素的添加、停留时长、移除、和移除后的回调
function App() {
this.state={
nodes : []
};
this.setState=function(state, callback){
this.state.nodes=state.nodes;
this.render();
if(callback){
callback()
}
};
this.add = function (node) {
const nodes =this.state.nodes;
node.class = 'move-up-enter';
nodes.push(node);
this.setState({
nodes
})
};
this.onRemove =function (node){
const self=this;
setTimeout(function(){
self.remove(node.key);
}, node.duration * 1000);
};
this.remove =function (key) {
const self=this;
const nodeStart = self.state.nodes;
const len = nodeStart.length;
let onClose;
for (let i = 0; i < len; i++) {
if (nodeStart[i].key === key) {
nodeStart[i].class = 'move-up-leave';
onClose = nodeStart[i].onClose;
break;
}
}
self.setState({
nodes: nodeStart
}, function() {
setTimeout(function() {
self.onClose(onClose);
const nodes = self.state.nodes.filter(
function (item) {
return item.key !== key;
});
self.setState({
nodes
});
}, 300);
});
};
this.onClose=function (onClose) {
return onClose();
};
this.render=function () {
const nodes =this.state.nodes;
ReactDOM.render(
React.createElement(
'div',
null,
nodes.map((node) => {
return React.createElement(
'div',
{key: node.key, className: `rcAlert-li ${node.class}`},
React.createElement(
'div',
{className: 'rcAlert-node'},
node.content,
)
)
})
), document.getElementById('myCat-rcAlert'));
}
}
复制代码
5. 回调函数:
判断是否有写入回调函数,并通过Promise的方式返回给原函数
function node(content) {
let duration = arguments.length > 1 && !isNaN(arguments[1]) ? arguments[1] : 3;
let type = arguments[2];
let onClose = arguments[3];
let iconType = {
info: '#icon-info',
success: '#icon-chenggong1',
error: '#icon-error',
warning: '#icon-warning',
}[type];
let iconClass = {
info: 'icon-info',
success: 'icon-success',
error: 'icon-error',
warning: 'icon-warning',
}[type];
key++;
let closePromise = new Promise(function (resolve) {
let callback = function callback() {
if (typeof onClose === 'function') {
onClose();
}
return resolve(true);
};
outerFrame(function (instance) {
instance.notice({
key: key,
duration: duration,
style: {},
content: React.createElement(
'div',
{className: 'rcAlert-node-content'},
React.createElement(
'svg',
{className: `icon rcAlert-icon ${iconClass}`},
React.createElement(
'use', {xlinkHref: iconType}
),
),
React.createElement(
'span',
null,
content
)
),
onClose: callback
})
}
);
});
let result = function result() {
if (rcAlertInstance) {
rcAlertInstance.removeNotice(target);
}
};
result.then = function (filled, rejected) {
return closePromise.then(filled, rejected);
};
result.promise = closePromise;
return result;
}
const rcAlert = {
info: function info(content, duration, onClose) {
return node(content, duration, 'info', onClose);
},
success: function success(content, duration, onClose) {
return node(content, duration, 'success', onClose);
},
error: function error(content, duration, onClose) {
return node(content, duration, 'error', onClose);
},
warn: function warn(content, duration, onClose) {
return node(content, duration, 'warning', onClose);
},
warning: function warning(content, duration, onClose) {
return node(content, duration, 'warning', onClose);
},
};
复制代码
NPM包总大小11k,使用简单便于调试!
GitHub:github.com/justcoolls/…