造个零依赖弹窗提示轮子.ts

引子

弹窗提示是项目基础设施之一.有UI框架的情况下使用框架提供的就行.
但有时候项目不大或者有限制甚至是没有脚手架的情况下,为了使用一个弹窗就引入一个UI框架显然是不现实的.在这个需求驱动下,开始折腾…

需求分析

期望的调用方式不用多想,与element-ui,vant一致即可.
期望的引入方式,umd格式,同时支持<script>直引与模块化引入.
期望的大小,这么简单的需求,当然是越小越好,所以不使用任何框架.0依赖原生开发.
另外,正好最近在学习ts,用ts实现,这样使用者使用时也有提示,更加友好.

代码组织

  1. ToastManager实例,接受一个配置对象,弹出不同的弹窗,到达指定时间删除自己.并且提供一个clear方法,可以提前删除实例.这部分没啥可说,略过不提.
  2. Toast方法.接受字符串或者配置对象,参数为字符串时,将其混入默认配置对象中,创建实例并返回.

    1
    2
    3
    4
    5
    6
    const Toast: ToastFn = function (opt) {
    instance = new ToastManager(fmtOpt(opt));
    instances.push(instance);
    seed++;
    return instance;
    };
  3. Toast的方法.
    把Toast当对象用,可以挂载方法
    clear,接受一个toast的id,清除指定实例;
    clearAll,清除已打开的所有实例;
    我们已经缓存了所有实例,很容易实现.

  4. Toast的别名.
    传对象太麻烦,特别是只是指定类型时,如Toast({message: '成功', type: 'success'}),Toast.success('成功')要省事点,为此可以实现一个extendAlias方法
    该方法接受一个配置对象,并利用闭包缓存这个配置对象,返回一个函数,调用时将配置对象合并并最终调用Toast方法

    1
    2
    3
    const extendAlias: extendFn = privateOption => option => Toast({...fmtOpt(option), ...privateOption});

    Toast.success = extendAlias({type: 'success'});

    这个方法暴露出去之后,也就相当于实现了更改默认配置的方法.

    1
    const myToast = extendAlias({type: 'icon-music', duration: 1000, mask: true});

类型.d.ts

打包后的代码是js,被ts引入时,无法获得提示,可以编写一个d.ts文件为其声明类型.
类型声明语法基本与普通ts一致,比较特殊的地方在于,Toast即是函数,也是对象.
查阅文档可知,可以d.ts文件会合并声明,实际上,jQuery也是这样的类型.按图索骥.
同时声明Toast为function和namespace即可.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
declare function Toast(options: string | managerType): ToastManager;

declare namespace Toast {
const clear: clearFn;
const clearAll: () => void;
const loading: aliasFn;
const waring: aliasFn;
const question: aliasFn;
const success: aliasFn;
const error: aliasFn;
const extendAlias: extendFn;
}

export default Toast