react无状态组件方式实现无需打包的npm包

实现目标

以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自动关闭的延时,单位秒number3秒
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/…

示例:liazm.com/#/rcAlert

转载于:https://juejin.im/post/5ce24f47e51d4510ab26bad9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值