“This is the 8th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021”

Front-end development is inevitable, and from time to time products will require a countdown feature; In addition to the differences in style, the functions are basically the same, so it is very meaningful to pull out the countdown function and form a package or library.

Ts syntax is used and eventemitter3 library extension is used to implement event-based notification (on, EMIT)

Several function points

About the design of countdown library:

  • The countdown should be instantiated with the new keyword
    import { EventEmitter } from 'eventemitter3';

    // Define enumeration of countdown events
    export enum CountdownEventName {
        START = 'start',
        STOP = 'stop',
        RUNNING = 'running',}// Inherit EventEmitter with on, emit, etc
    export class Countdown extends EventEmitter<CountdownEventMap> {}Copy the code
  • The instantiated countdown should accept an end time and also a number of steps (the interval between each beat)
    constructor(endTime: number, step: number = 1e3) {
        super(a);// Save the initial data
        this.endTime = endTime;
        this.step = step;

    }
Copy the code
  • The instantiated countdown should have its own state
    // Define some enumerations

    // The format of the data returned
    export interface RemainTimeData {
        /** 天数 */
        days: number;
        /** * Number of hours */
        hours: number;
        /** * Number of minutes */
        minutes: number;
        /** * number of seconds */
        seconds: number;
        /** * milliseconds */
        count: number;
    }

    // State enumeration
    enum CountdownStatus {
        running,
        paused,
        stoped,
    }

    // Event enumeration
    export enum CountdownEventName {
        START = 'start',
        STOP = 'stop',
        RUNNING = 'running',}// Format method 9 -> 09
    export function fillZero(num: number) {
        return ` 0${num}`.slice(-2);
    }
Copy the code
  • The instantiated countdown should return the formatted time (days, hours, minutes, seconds) when changed.

  • Instantiated countdowns should provide both start and end apis

    public start() {
        // Throw the event countdown to start
        this.emit(CountdownEventName.START);

        this.status = CountdownStatus.running;

        // The countdown method
        this.countdown();
    }

    public stop() {
        // Drop event countdown stops
        this.emit(CountdownEventName.STOP);

        this.status = CountdownStatus.stoped;
    }
Copy the code

About library packaging:

  • The result should be a library that runs under all module definitions

  • It should be possible to use different files (compressed | uncompressed) depending on the current environment (development | production)

The specific implementation

The countDown method is actually very simple:

  • Take the end time minus the present time to get the remaining time

  • Check whether the remaining time is greater than 0: if the remaining time is greater than 0, format the remaining time, emit data outward, and then update the remaining time (subtract step);

  • Repeat the second step until the countdown is less than or equal to zero, ending the countdown

Webpack builds:

  • LibraryTarget can be set to umD for all module definitions using the Output. library configuration item of WebPack.

  • For libraries, it is generally necessary to provide the min version and the uncompressed version. You can configure two portals in Webpack, and then compress the min version using the Terser-webpack-plugin

Full version code address: countDownJs