开发常用工具函数——个人存档

109 阅读3分钟

1、数组转映射


export const arrayToMap = (arr: Array<any>, key: string) => {

  if (!Array.isArray(arr) || !key) return;

  return arr.reduce((res, item) => {

    const k = item[key];

    if (k || k === 0) res[k] = item;

    return res;

  }, {});

};

2、tree-->平级


export const generateList = (data: Array<any>, key = 'children') => {

  const dataList: Array<any> = [];

  dealData(data);

  function dealData(data: Array<any>) {

    for (let i = 0; i < data.length; i++) {

      const node = data[i];

      dataList.push(node);

      if (node?.[key]) {

        dealData(node?.[key]);

      }

    }

  }

  return dataList;

};

3、平级-->tree 结构


export const getChildrenList = ({

  data,

  id = 'id',

  pid = 'pid',

}: {

  data: Array<any>;

  id?: string;

  pid?: string;

}) => {

  const info = data.reduce((pre, node) => {

    pre[node[id]] = node;

    node.children = [];

    return pre;

  }, {});

  const arr = data.filter((node) => {

    if (info[node[pid]]) {

      info[node[pid]].children.push(node);

    }

    return !node[pid] || node[pid] === '0' || node[pid] === 0; //注意有些pid值为字符0时 判断会有问题

  });

  return arr || [];

};

4、构建 TreeSelect 相关字段


export function createSelectData({

  data = [],

  children = 'children',

  title = 'label',

  value = 'value',

}: {

  data: Array<any>;

  children?: string;

  title?: string;

  value?: string;

}) {

  const list: Array<any> = (data || []).map((item) => {

    let childrenList = [];

    if (Array.isArray(item?.[children])) {

      childrenList = createSelectData({

        data: item?.[children],

        title,

        value,

        children,

      });

    }

    return {

      ...item,

      title: item?.[title],

      value: item?.[value],

      children: childrenList,

    };

  });

  return list;

}

5、从数组中随机抽取任意数量的元素


function getRandomArrayElements(arr, count) {

  var shuffled = arr.slice(0),

    i = arr.length,

    min = i - count,

    temp,

    index;

  while (i-- > min) {

    index = Math.floor((i + 1) * Math.random());

    temp = shuffled[index];

    shuffled[index] = shuffled[i];

    shuffled[i] = temp;

  }

  return shuffled.slice(min);

}

6、时间日期格式转换


import { Moment } from 'moment';

// 转换显示日期

export const dateYMDHMS = (date: Moment): string => {

  return date.format('YYYY-MM-DD HH:mm:ss');

};

export const dateYMD = (date: Moment): string => {

  return date.format('YYYY-MM-DD');

};

export const dateHMS = (date: Moment): string => {

  return date.format('HH:mm:ss');

};

//获取momemt对象

export const getMoment = (str: string): Moment => {

  if (moment(str).isValid()) {

    return moment(str);

  }

  return new Error('时间日期字符串不符合格式');

};

7、阻止冒泡事件


export const stopPropagation = (e) => {

  e = e || window.event;

  if (e.stopPropagation) {

    // W3C阻止冒泡方法

    e.stopPropagation();

  } else {

    e.cancelBubble = true; // IE阻止冒泡方法

  }

};

8、防抖函数


export const debounce = (fn, wait) => {

  let timer = null;

  return function () {

    let context = this,

      args = arguments;

    if (timer) {

      clearTimeout(timer);

      timer = null;

    }

    timer = setTimeout(() => {

      fn.apply(context, args);

    }, wait);

  };

};


export const useDebounce = (fn, delay, dep: any = []) => {

  useEffect(() => {

    let timer: any = null;

    timer = setTimeout(fn, delay);

    return () => clearTimeout(timer);

    // eslint-disable-next-line react-hooks/exhaustive-deps

  }, [...dep]);

};

9、节流函数


export const throttle = (fn, delay) => {

  let curTime = Date.now();

  return function () {

    let context = this,

      args = arguments,

      nowTime = Date.now();

    if (nowTime - curTime >= delay) {

      curTime = Date.now();

      return fn.apply(context, args);

    }

  };

};

10、数据类型判断


export const getType = (value: any) => {

  if (value === null) {

    return value + '';

  }

  // 判断数据是引用类型的情况

  if (typeof value === 'object') {

    let valueClass = Object.prototype.toString.call(value),

      type = valueClass.split(' ')[1].split('');

    type.pop();

    return type.join('').toLowerCase();

  } else {

    // 判断数据是基本数据类型的情况和函数的情况

    return typeof value;

  }

};

11、数字格式化:千分位、百分比


import React from 'react';

import { useIntl } from '@/umi';

import _ from 'lodash';

import { useCallback } from 'react';

import { FormatNumberOptions } from 'react-intl';

export type UseFormatNumberOptions = {

  /**

   * 用于渲染格式化后的文案

   * @param value

   */

  render?: (value: React.ReactNode) => React.ReactNode;

} & FormatNumberOptions;

/**

 * 格式化数字

 */

export const useFormatNumber = () => {

  const intl = useIntl();

  const formatNumber = useCallback(

    (value: any, options?: UseFormatNumberOptions) => {

      const { render, ...restOptions } = Object.assign(

        {

          render: _.identity,

        },

        options,

      );

      return render(

        _.isNumber(value) ? intl.formatNumber(value, restOptions) : '--',

      );

    },

    [intl],

  );

  const formatRate = useCallback(

    (value: any, options?: UseFormatNumberOptions) => {

      const { render, ...restOptions } = Object.assign(

        {

          render: _.identity,

          maximumFractionDigits: 2,

        },

        options,

      );

      return render(

        _.isNumber(value)

          ? `${intl.formatNumber(value * 100, restOptions)}%`

          : '--',

      );

    },

    [intl],

  );

  return {

    /**

     * 格式化数字千分位分隔

     * @example

     * formatNumber(123456); //123,456

     */

    formatNumber,

    /**

     * 格式化比率

     * @example

     * formatRate(0.1234456) // 12.35%

     */

    formatRate,

  };

};

12、isNilEmpty 判断数据是否是 null undefined {} [] ''


import _ from 'lodash';

/**

 * 如果数据是 null undefined {} [] '',返回true 其他返回false

 * @param value

 * @returns {boolean}

 */

const isNilEmpty = (value: any): value is null | undefined | '' | Record<string, never> | [] => {

  if (_.isString(value)) {

    return value.length === 0;

  }

  if (_.isObject(value)) {

    return _.isEmpty(Object.keys(value));

  }

  if (_.isArray(value)) {

    return _.isEmpty(value.length);

  }

  return _.isNil(value);

};

13、驼峰命名转换成短横线命名

export const getKebabCase = (str) => {

  return str.replace(/[A-Z]/g, (item) => '-' + item.toLowerCase());

};

14、短横线命名转换成驼峰命名

export const getCamelCase = (str) => {

  return str.replace(/-([a-z])/g, (i, item) => item.toUpperCase());

};

15、数字转化为大写金额

export const digitUppercase = (n) => {

  const fraction = ['角', '分'];

  const digit = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'];

  const unit = [

    ['元', '万', '亿'],

    ['', '拾', '佰', '仟'],

  ];

  n = Math.abs(n);

  let s = '';

  for (let i = 0; i < fraction.length; i++) {

    s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');

  }

  s = s || '整';

  n = Math.floor(n);

  for (let i = 0; i < unit[0].length && n > 0; i++) {

    let p = '';

    for (let j = 0; j < unit[1].length && n > 0; j++) {

      p = digit[n % 10] + unit[1][j] + p;

      n = Math.floor(n / 10);

    }

    s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;

  }

  return s

    .replace(/(零.)*零元/, '元')

    .replace(/(零.)+/g, '零')

    .replace(/^整$/, '零元整');

};

16、数字转化为中文数字

export const intToChinese = (value) => {

  const str = String(value);

  const len = str.length - 1;

  const idxs = ['', '十','百','千','万','十','百','千','亿','十','百','千','万','十','百','千','亿',];

  const num = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九'];

  return str.replace(/([1-9]|0+)/g, ($, $1, idx, full) => {

    let pos = 0;

    if ($1[0] !== '0') {

      pos = len - idx;

      if (idx == 0 && $1[0] == 1 && idxs[len - idx] == '十') {

        return idxs[len - idx];

      }

      return num[$1[0]] + idxs[len - idx];

    } else {

      let left = len - idx;

      let right = len - idx + $1.length;

      if (Math.floor(right / 4) - Math.floor(left / 4) > 0) {

        pos = left - (left % 4);

      }

      if (pos) {

        return idxs[pos] + num[$1[0]];

      } else if (idx + $1.length >= len) {

        return '';

      } else {

        return num[$1[0]];

      }

    }

  });

};

17、获取 URL 参数列表


export const GetRequest = () => {

  let url = location.search || '';

  const paramsStr = /.+\?(.+)$/.exec(url)?.[1]; // 将 ? 后面的字符串取出来

  if (paramsStr) {

    const paramsArr = paramsStr.split('&'); // 将字符串以 & 分割后存到数组中

    let paramsObj: any = {};

    // 将 params 存到对象中

    paramsArr.forEach((param) => {

      if (/=/.test(param)) {

        // 处理有 value 的参数

        let [key, val]: Array<any> = param.split('='); // 分割 key 和 value

        val = decodeURIComponent(val); // 解码

        val = /^\d+$/.test(val) ? parseFloat(val) : val; // 判断是否转为数字

        if (paramsObj.hasOwnProperty(key)) {

          // 如果对象有 key,则添加一个值

          paramsObj[key] = [].concat(paramsObj[key], val);

        } else {

          // 如果对象没有这个 key,创建 key 并设置值

          paramsObj[key] = val;

        }

      } else {

        // 处理没有 value 的参数

        paramsObj[param] = true;

      }

    });

    return paramsObj;

  }

  return {};

};

18、检测 URL 是否有效


export const getUrlState = (URL: string) => {

  let xmlhttp = new ActiveXObject('microsoft.xmlhttp');

  xmlhttp.Open('GET', URL, false);

  try {

    xmlhttp.Send();

  } catch (e) {

  } finally {

    let result = xmlhttp.responseText;

    if (result) {

      if (xmlhttp.Status == 200) {

        return true;

      } else {

        return false;

      }

    } else {

      return false;

    }

  }

};

19、键值对拼接成 URL 参数


export const params2Url = <T>(obj: T): string => {

  let params = [];

  for (let key in obj) {

    params.push(`${key}=${obj[key]}`);

  }

  return encodeURIComponent(params.join('&'));

};

20、修改 URL 中的参数


export const replaceParamVal = <T>(paramName: string, replaceWith: T): string => {

  const oUrl = location.href.toString();

  const re = eval('/(' + paramName + '=)([^&]*)/gi');

  location.href = oUrl.replace(re, paramName + '=' + replaceWith);

  return location.href;

};

21、删除 URL 中指定参数

export const funcUrlDel = (name: string): string => {

  const baseUrl = location.origin + location.pathname + '?';

  const query = location.search.substr(1);

  if (query.indexOf(name) > -1) {

    const obj: any = {};

    const arr: Array<any> = query.split('&');

    for (let i = 0; i < arr.length; i++) {

      arr[i] = arr[i].split('=');

      obj[arr[i][0]] = arr[i][1];

    }

    delete obj[name];

    return (

      baseUrl +

      JSON.stringify(obj)

        .replace(/[\"\{\}]/g, '')

        .replace(/\:/g, '=')

        .replace(/\,/g, '&')

    );

  }

  return location.href;

};