background

Enumeration values are always used in front-end development, and our application scenarios for enumeration values are as follows:

  • The enumeration type of the page drop-down box and the numeric quantity corresponding to the enumeration type
  • The background returns the number quantity, the front end needs to display the corresponding text description

We used to keep the data sources in different places. In fact, I still want to manage the data sources in a unified place, and then make a variation based on the data source, one to support enumeration variables, and one to support numeric quantities corresponding to the text description returned


Js version

Function load through the data source + enumeration injection = “to generate the corresponding object, want to use the method through the method directly get good.



Index.js enumerates entry files

CommonEnum Index is a utility function that returns the corresponding enumeration object when a service file is called.

/* eslint-disable camelcase */
import _ from "lodash";
import sourceData from "./sourceData";

const highForatFunction = enumSourceData= > {
  // Returns an enumeration type based on data source processing
  const enumValue = {};

  _.forEach(enumSourceData, item= > {
    enumValue[item.key] = item.value;
  });

  // Enumerates data sources to get lable text values based on value values
  const getLabelByValue = value= > {
    const filterObject = _.filter(enumSourceData, item= > item.value === value);

    // There is a return value, which returns the first matching data
    if (filterObject.length) {
      return filterObject[0].label;
    }

    // If no value is returned, nothing is returned
    return "";
  };

  return {
    enum: enumValue,
    getLabelByValue
  };
};

const injectEnumFunction = sourceDataKeyArray= > {
  // Data type check
  if(! _.isArray(sourceDataKeyArray)) {throw new Error("Injection failed, parameter format is incorrect");
  }

  const injectEnumOject = {};

  _.forEach(sourceDataKeyArray, item= > {
    // eslint-disable-next-line no-prototype-builtins
    if (sourceData.hasOwnProperty(item)) {
      injectEnumOject[item] = highForatFunction(sourceData[item]);
    } else {
      throw new Error('Injection failed, no${item}Corresponding enumeration data '); }});return injectEnumOject;
};

export default injectEnumFunction;

Copy the code


Sourcedata.js Data source file

Data source file: enumerates every single object inside the topic, with three internal property values: key, value, label.

const sourceData = {
  userAccountTypeEnum: [{key: "STAFF".value: 1.label: "Employees"
    },
    {
      key: "COMPANY".value: 2.label: "The company"}};export default sourceData;

Copy the code


use





The introduction of injectEnumFunction

import injectEnumFunction from "@/common/commonEnum";
Copy the code

Call method, injecting the userAccountTypeEnum enum type value

const { userAccountTypeEnum } = injectEnumFunction(["userAccountTypeEnum"]);
Copy the code

The result is:



The result is two properties, one of which is an enum enum value. The other is a function that gets the corresponding text information from the key value.





Dumi & TS version

Making the source code

Create a project

Dumi website

yarn create @umijs/dumi-lib --site
Copy the code



The code structure





The core code

// index.ts
import _ from 'lodash';
import {
  EnumItem,
  EnumBase,
  TypeEnum,
  InjectEnumObject,
  SourceData,
} from './type';

class EnumStoreClass {
  private _sourceData: SourceData = {};

  private _highForatFunction = (enumSourceData: EnumItem[]) = > {
    // Returns an enumeration type based on data source processing
    const enumValue: EnumBase = {};

    _.forEach(enumSourceData, (item) = > {
      enumValue[item.key] = item.value;
    });

    // Enumerates data sources to get lable text values based on value values
    const getLabelByValue = (value: TypeEnum) = > {
      const filterObject = _.filter(
        enumSourceData,
        (item) = > item.value === value,
      );

      // There is a return value, which returns the first matching data
      if (filterObject.length) {
        return filterObject[0].label;
      }

      // If no value is returned, nothing is returned
      return ' ';
    };

    return {
      enum: enumValue,
      getLabelByValue,
    };
  };

  public initData(initData: SourceData) {
    this._sourceData = initData;
  }

  public injectEnumFunction = (sourceDataKeyArray: string[]) = > {
    // Data type check
    if(! _.isArray(sourceDataKeyArray)) {throw new Error('Injection failed, parameter format is incorrect');
    }

    const injectEnumOject: InjectEnumObject = {};

    _.forEach(sourceDataKeyArray, (item) = > {
      // eslint-disable-next-line no-prototype-builtins
      if (this._sourceData.hasOwnProperty(item)) {
        injectEnumOject[item] = this._highForatFunction(this._sourceData[item]);
      } else {
        throw new Error('Injection failed, no${item}Corresponding enumeration data '); }});return injectEnumOject;
  };
}

const enumStore = new EnumStoreClass();

export const initEnumSourceData = (initData: SourceData) = > {
  enumStore.initData(initData);
};

export const injectEnumFunction = (sourceDataKeyArray: string[]) = > {
  return enumStore.injectEnumFunction(sourceDataKeyArray);
};

export * from './type';
Copy the code
// type.ts
export type TypeEnum = number | string;

export interface EnumItem {
  key: TypeEnum;
  label: TypeEnum;
  value: TypeEnum;
}

export interface EnumBase {
  [key: number]: TypeEnum;
  [key: string]: TypeEnum;
}

export interface InjectEnumItem {
  enum? : EnumBase; getLabelByValue? :Function;
}

export interface InjectEnumObject {
  [key: string]: InjectEnumItem;
}

export interface SourceData {
  [key: string]: EnumItem[];
}

Copy the code


use

import React from 'react';
import { injectEnumFunction, initEnumSourceData, SourceData } from 'rofo-enum';

const sourceData: SourceData = {
  userAccountTypeEnum: [{key: 'STAFF'.value: 1.label: 'employees'}, {key: 'COMPANY'.value: 2.label: 'the company',}]};for (let i = 0; i < 10000; i++) {
  sourceData['userAccountTypeEnum' + i] = [
    {
      key: 'STAFF'.value: 1.label: 'employees'}, {key: 'COMPANY'.value: 2.label: 'the company',},]; } initEnumSourceData(sourceData);console.time('test-start');
const { userAccountTypeEnum9999 } = injectEnumFunction([
  'userAccountTypeEnum9999',]);console.log(userAccountTypeEnum9999.enum);

console.log(userAccountTypeEnum9999.getLabelByValue(1));

console.timeEnd('test-start');
Copy the code

The performance test

Console. time is used for performance testing. Because it is property access, there is no performance impact.




How to debug locally

When we have not published the code to NPM, we can set the following locally:







The sample can then be tested directly with code like the following:

import { injectEnumFunction, initEnumSourceData, SourceData } from 'rofo-enum';
Copy the code




Publish online NPM packages

When we write the code, write the online documentation, submit the code, and release the version.

npm run release
Copy the code





Then go to the NPM website and you can see the published package.



www.npmjs.com/package/rof…







Publish online documents

npm run deploy
Copy the code





Then go to the corresponding Github project address to see the GH-Pages branch









Click to view: the page is blank, the main reason is that the path access here is a secondary domain name, so we need to modify the code.









This is for the Github deployment site







And then we can see what we deployWeb site