搭建组件库使用的一些方法

目录

1. 校验类方法

1.1 判断是否为数字

1.2 判断变量是否定义

2. 常见业务常量

2.1 污染物格式

2.1.1 html 标签封装的污染物

2.1.2 echarts 图表中可以直接复制的污染物

2.1.3 将 接口返回的字段名 转换为 可直接使用的污染物

2.2 AQI 文字等级及对应颜色

2.3 Echarts 图默认选项

2.3.1 关于 Object.freeze

2.3.2 默认选项

2.3.3  X/Y坐标轴选项

3. 工具方法

3.1 定义数据类型接口

3.2 生成指定长度的随机字符串

3.3 将 css 样式对象转换为字符串

3.4 生成元素的随机 class 名

3.5 根据 cStyle 设置元素样式

3.6 添加单位

3.7 过滤 attr 属性

3.8 过滤元素样式

3.9 颜色格式转换

3.10 将数组拆分成指定个数的分组数组

3.11 生成随机 uuid

3.12 业务方法

3.12.1 获取 AQI 等级

3.12.2 获取污染物 html,不存在则原样返回

3.12.3 替换一段字符串中所有污染物为正确格式

4. 创建动态类名

4.1 BEM HELPER

4.2 创建命名空间

5. 获取并设置 cookies 中的语言类型

6. 主题换肤处理

6.1 修改主题色及背景色

6.2 设置颜色变量值

6.3 修改主题风格下的颜色变量

6.4 设置主题及背景色、设置主题风格下的颜色变量

6.5 将设置主题色及颜色变量的方法封装为 hooks


1. 校验类方法

1.1 判断是否为数字

export const isNumeric = (val: string | number): val is string => typeof val === 'number' || /^\d+(\.\d+)?$/.test(val);

1.2 判断变量是否定义

export const isDef = <T>(val: T): val is NonNullable<T> => val !== undefined && val !== null;

2. 常见业务常量

2.1 污染物格式

2.1.1 html 标签封装的污染物

export const POLLUTION_HTML = [
  {
    name: 'O3',
    html: 'O<small><sub>3</sub></small>',
  },
  {
    name: 'PM10',
    html: 'PM<small><sub>10</sub></small>',
  },
  {
    name: 'PM25',
    html: 'PM<small><sub>2.5</sub></small>',
  },
  {
    name: 'SO2',
    html: 'SO<small><sub>2</sub></small>',
  },
  {
    name: 'SO3',
    html: 'SO<small><sub>3</sub></small>',
  },
  {
    name: 'CO',
    html: 'CO',
  },
  {
    name: 'CODMN',
    html: 'COD<small><sub>mn</sub></small>',
  },
  {
    name: 'VOCS',
    html: 'VOC<small><sub>s</sub></small>',
  },
  {
    name: 'NO',
    html: 'NO',
  },
  {
    name: 'NO2',
    html: 'NO<small><sub>2</sub></small>',
  },
  {
    name: 'NH3',
    html: 'NH<small><sub>3</sub></small>',
  },
  {
    name: 'NOX',
    html: 'NO<small><sub>x</sub></small>',
  },
  {
    name: 'NH4',
    html: 'NH<small><sub>4</sub><sup>+</sup></small>',
  },
  {
    name: 'MNO4',
    html: 'MnO<small><sub>4</sub><sup>-</sup></small>',
  },
  {
    name: 'PH',
    html: 'pH',
  },
];

2.1.2 echarts 图表中可以直接复制的污染物

export const POLLUTION_CHARTS = [
  {
    name: 'O3',
    html: 'O₃',
  },
  {
    name: 'PM10',
    html: 'PM₁₀',
  },
  {
    name: 'PM25',
    html: 'PM₂.₅',
  },
  {
    name: 'SO2',
    html: 'SO₂',
  },
  {
    name: 'SO3',
    html: 'SO₃',
  },
  {
    name: 'CO',
    html: 'CO',
  },
  {
    name: 'CODMN',
    html: 'CODmn',
  },
  {
    name: 'VOCS',
    html: 'VOCs',
  },
  {
    name: 'NO',
    html: 'NO',
  },
  {
    name: 'NO2',
    html: 'NO₂',
  },
  {
    name: 'NH3',
    html: 'NH₃',
  },
  {
    name: 'NOX',
    html: 'NOx',
  },
  {
    name: 'NH4',
    html: 'NH₄⁺',
  },
  {
    name: 'MNO4',
    html: 'MnO₄¯',
  },
  {
    name: 'PH',
    html: 'pH',
  },
];

2.1.3 将 接口返回的字段名 转换为 可直接使用的污染物

export const POLLUTION_CHARTS_ALL = [
  {
    name: ['O3', 'o3'],
    html: 'O₃',
  },
  {
    name: ['PM10', 'pm10'],
    html: 'PM₁₀',
  },
  {
    name: ['PM25', 'PM2_5', 'PM2.5', 'pm25', 'pm2_5', 'pm25'],
    html: 'PM₂.₅',
  },
  {
    name: ['SO2', 'so2'],
    html: 'SO₂',
  },
  {
    name: ['SO3', 'so3'],
    html: 'SO₃',
  },
  {
    name: ['CO2', 'co2'],
    html: 'CO₂',
  },
  {
    name: ['CODMN', 'codmn'],
    html: 'CODmn',
  },
  {
    name: ['VOCS', 'vocs'],
    html: 'VOCs',
  },
  {
    name: ['no'],
    html: 'NO',
  },
  {
    name: ['NO2', 'no2'],
    html: 'NO₂',
  },
  {
    name: ['NH3', 'nh3'],
    html: 'NH₃',
  },
  {
    name: ['NOX', 'nox'],
    html: 'NOx',
  },
  {
    name: ['NH4', 'nh4'],
    html: 'NH₄⁺',
  },
  {
    name: ['MNO4', 'mno4'],
    html: 'MnO₄¯',
  },
  {
    name: ['PH', 'ph'],
    html: 'pH',
  },
];

2.2 AQI 文字等级及对应颜色

// AQI 等级 1-6 级,7 为无数据时
export const AQI_TYPE = {
  1: '优',
  2: '良',
  3: '轻度污染',
  4: '中度污染',
  5: '重度污染',
  6: '严重污染',
  7: '-',
};

// AQI 等级颜色 1-6 级,7 为无数据颜色
export const AQI_COLOR = {
  1: '#05CE04',
  2: '#FCFE03',
  3: '#FF6600',
  4: '#FE0000',
  5: '#9820F4',
  6: '#800000',
  7: '#777',
};

2.3 Echarts 图默认选项

2.3.1 关于 Object.freeze

用 Object.freeze() 定义一个不可被修改的对象(冻结对象),被冻结的对象有以下特性:

  • 不能添加新属性
  • 不能删除已有属性
  • 不能修改已有属性的值
  • 不能修改原型
  • 不能修改已有属性的可枚举性、可配置性、可写性

参考文章:

Object.freeze()详解_韭五后的博客-CSDN博客_object.freeze我们都知道const定义基本数据类型,这个值是不可以修改的。那么我们用const定义对象,可以修改对象吗?const a = 5// a = 10 // TypeError: Assignment to constant variable.const obj = { name: '张三'}obj.name = '李四'console.log(obj) // {name: "李四"}答案是肯定的。那么如果我们想定义一个不可被修改的对象,应该怎么办呢!那就要用到Object.https://blog.csdn.net/cai_niao5623/article/details/121095017

2.3.2 默认选项

export const DEFAULT_OPTIONS = Object.freeze({
  color: [
    '#2ec7c9',
    '#b6a2de',
    '#5ab1ef',
    '#ffb980',
    '#d87a80',
    '#8d98b3',
    '#e5cf0d',
    '#97b552',
    '#95706d',
    '#dc69aa',
    '#07a2a4',
    '#9a7fd1',
    '#588dd5',
    '#f5994e',
    '#c05050',
    '#59678c',
    '#c9ab00',
    '#7eb00a',
    '#6f5553',
    '#c14089',
  ],
  backgroundColor: 'rgba(0,0,0,0)',
  textStyle: {},
  title: {
    show: false,
    text: '标题',
    padding: [5, 5, 5, 5],
    left: 'left',
    top: 'top',
    textStyle: {
      color: '#008acd',
    },
    subtextStyle: {
      color: '#aaaaaa',
    },
  },
  toolbox: {
    iconStyle: {
      borderColor: '#2ec7c9',
    },
    emphasis: {
      iconStyle: {
        borderColor: '#18a4a6',
      },
    },
  },
  legend: {
    show: true,
    padding: [10, 5, 5, 5],
    textStyle: {
      color: '#333333',
    },
  },
  tooltip: {
    trigger: 'axis',
    axisPointer: {
      lineStyle: {
        color: '#008acd',
        width: '1',
      },
      crossStyle: {
        color: '#008acd',
        width: '1',
      },
    },
  },
  markPoint: {
    label: {
      color: '#eeeeee',
    },
    emphasis: {
      label: {
        color: '#eeeeee',
      },
    },
  },
  valueAxis: {
    axisLine: {
      show: false,
    },
    axisTick: {
      show: false,
    },
    axisLabel: {
      show: true,
    },
    splitLine: {
      show: false,
    },
    splitArea: {
      show: false,
    },
  },
  dataZoom: [
    {
      // 禁用缩放
      disabled: true,
      type: 'inside',
      start: 0,
      end: 100,
      preventDefaultMouseMove: true,
    },
    {
      // 隐藏滑块
      show: false,
      type: 'slider',
      start: 0,
      end: 100,
      height: 12,
      borderColor: 'transparent',
      backgroundColor: '#f8f8f8',
      dataBackground: {
        lineStyle: {
          width: 0,
        },
        areaStyle: {
          color: 'transparent',
        },
      },
      fillerColor: '#e1e1e1',
      handleIcon: 'path://path://M100, 100m -75, 0a75,75 0 1,0 150,0a75,75 0 1,0 -150,0',
      handleStyle: {
        color: '#fff',
        shadowColor: 'rgba(0, 0, 0, 0.2)',
        shadowBlur: 4,
      },
      handleSize: '100%',
      textStyle: {
        color: '#888',
      },
      bottom: '10px',
    },
  ],
});

2.3.3  X/Y坐标轴选项

export const DEFAULT_OPTIONS_AXIS = Object.freeze({
  // X轴配置
  xAxis: {
    show: true,
    name: '',
    type: 'category',
    nameTextStyle: {
      align: 'left',
      color: '#666',
      fontSize: '12',
      fontFamily: 'PF',
    },
    nameGap: 5,
    boundaryGap: false,
    axisLine: {
      show: true,
      lineStyle: {
        color: '#cacaca',
        width: 1,
        type: 'solid',
      },
    },
    axisTick: {
      show: false,
      lineStyle: {
        color: '#333',
      },
    },
    splitLine: {
      show: false,
      lineStyle: {
        color: 'rgba(202,202,202,0.3)',
        width: 1,
        type: 'solid',
      },
    },
    axisLabel: {
      show: true,
      rotate: 0,
      color: '#666',
      fontSize: '12',
      fontFamily: 'PF',
      margin: 10,
    },
  },
  // y轴配置
  yAxis: {
    show: true,
    name: '',
    nameLocation: 'end',
    type: 'value',
    nameTextStyle: {
      color: '#666',
      fontSize: '12',
      fontFamily: 'PF',
      align: 'left',
      padding: [0, 0, 7, -24],
    },
    nameGap: 10,
    inverse: false,
    boundaryGap: false,
    splitNumber: 5,
    axisLine: {
      show: true,
      lineStyle: {
        color: '#cacaca',
        width: 1,
        type: 'solid',
      },
    },
    axisTick: {
      show: false,
    },
    splitLine: {
      show: true,
      lineStyle: {
        color: 'rgba(202,202,202,0.3)',
        width: 1,
        type: 'solid',
      },
    },
    axisLabel: {
      show: true,
      interval: 0,
      rotate: 0,
      color: '#666',
      fontSize: '12',
      fontFamily: 'PF',
      formatter: '{value}',
      align: 'right',
    },
  },
});

3. 工具方法

3.1 定义数据类型接口

export type MouseState = 'default' | 'hover' | 'focus' | 'active' | 'finish';

// 组件自定义样式
export interface ComponentCustomStyle {
  // 组件最外层 必填
  wrapper: SetInternalElementStyleOptions;
  // 组件内部需要设置样式的元素 例如 icon button text 等
  [n: string]: SetInternalElementStyleOptions;
}

// 设置组件内置元素样式
export interface SetInternalElementStyleOptions {
  // 默认
  default: CssProperty;
  // 选中
  active?: CssProperty;
  // 滑过
  hover?: CssProperty;
  // 聚焦
  focus?: CssProperty;
  // 完成状态
  finish?: CssProperty;
  // 出错状态
  error?: CssProperty;
  // 禁用状态
  disabled?: CssProperty;
  // 禁用选中状态
  disabledActive?: CssProperty;
}

// css 属性
export interface CssProperty {
  [n: string]: string | number;
}

3.2 生成指定长度的随机字符串

/**
 * @description: 随机字符串
 * @param {*} pasLen 字符串长度
 * @return {*}
 */
export const getRandomStr = (pasLen) => {
  const pasArr = [
    'a',
    'b',
    'c',
    'd',
    'e',
    'f',
    'g',
    'h',
    'i',
    'j',
    'k',
    'l',
    'm',
    'n',
    'o',
    'p',
    'q',
    'r',
    's',
    't',
    'u',
    'v',
    'w',
    'x',
    'y',
    'z',
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'G',
    'H',
    'I',
    'J',
    'K',
    'L',
    'M',
    'N',
    'O',
    'P',
    'Q',
    'R',
    'S',
    'T',
    'U',
    'V',
    'W',
    'X',
    'Y',
    'Z',
    '0',
    '1',
    '2',
    '3',
    '4',
    '5',
    '6',
    '7',
    '8',
    '9',
  ];
  let pwdResult = '';
  const pasArrLen = pasArr.length;
  for (let i = 0; i < pasLen; i++) {
    const x = Math.floor(Math.random() * pasArrLen);
    pwdResult += pasArr[x];
  }
  return pwdResult;
};

3.3 将 css 样式对象转换为字符串

/**
 * @description: 将css样式对象转换为字符串
 * @param {CssProperty} CssProperty css样式对象
 * @return {string} str
 */
export const getCssPropertyString = (cssProperty: CssProperty = {}) => {
  let str = '';
  Object.keys(cssProperty).forEach((key) => {
    if (key && cssProperty) {
      const cssPropertyName = key.replace(/([A-Z])/g, (match, p1) => `-${p1.toLowerCase()}`);
      str += `${cssPropertyName}: ${cssProperty[key]};`;
    }
  });
  return str;
};

3.4 生成元素的随机 class 名

/**
 * @description: 获取元素随机class名称
 * @param {string} classNamePrefix DOM节点class名前缀
 * @return {*} 随机class
 */
export const getDomRandomClass = (classNamePrefix: string) => `${classNamePrefix}-${getRandomStr(16)}`;

3.5 根据 cStyle 设置元素样式

/**
 * @description: 根据cStyle设置元素样式
 * @param {SetInternalElementStyleOptions} cStyleItem 传入的样式cStyle
 * @param {string} selectorString 样式选择器
 * @returns {string} 整合好的样式
 */
export const setStyle = (
  cStyleItem: SetInternalElementStyleOptions,
  selectorString: string,
) => {
  let innerHtml = '';
  Object.keys(cStyleItem).forEach((key) => {
    const state = key as MouseState;
    // 过滤掉:active的伪类样式
    if (state === 'active') {
      return;
    }
    // 兼容selectorString为并集选择器时的css样式代码
    const newSelectorString = selectorString
      .split(',')
      .map((singleSelector) => `${singleSelector}:${state}`)
      .join(',');
    innerHtml
      += state === 'default'
        ? `
            ${selectorString} {
              ${getCssPropertyString(cStyleItem[state])}
            }
          `
        : `
            ${newSelectorString} {
              ${getCssPropertyString(cStyleItem[state])}
            }
          `;
  });
  return innerHtml;
};

3.6 添加单位

传入数字,则拼接为 px,传入字符串,则保留字符串

/**
 * @description: 添加单位
 * @param {string} value
 * @return {*} 带单位数据
 */
export function addUnit(value?: string | number): string {
  if (!isDef(value)) {
    return '';
  }
  return isNumeric(value) ? `${value}px` : String(value);
}

3.7 过滤 attr 属性

/**
 * @description: 过滤attr属性
 * @param obj 需要过滤的对象
 * @param customAttr 自定义需要过滤的属性名称
 * @return 过滤后的对象
 */
export function filterAttrs(obj: any, customAttr: string[] = []) {
  const resObj: any = {};
  Object.keys(obj).forEach((key: string) => {
    const keys = [
      'data-id',
      'id',
      'cStyle',
      'class',
      'style',
      'onClick',
      'onDblclick',
      'onMousedown',
      'onMouseup',
      'onMousemove',
      'onMouseover',
      'onMouseout',
      'onMouseenter',
      'onMouseleave',
      'onAnimationstart',
      'onAnimationend',
      'onAnimationiteration',
      'onTransitionend',
    ].concat(customAttr);
    const include = keys.reduce((x: boolean, y: string) => x || key === y, false);
    if (!include) {
      resObj[key] = obj[key];
    }
  });
  return resObj;
}

3.8 过滤元素样式

// 过滤样式定义
interface Style {
  [propName: string]: any
}

/**
 * 过滤元素样式
 * @param styles 样式
 */
export const getStyle = (styles: Style) => {
  const keys = [
    'width',
    'height',
    'top',
    'left',
    'rotate',
    'fontSize',
    'marginTop',
    'marginLeft',
    'marginBottom',
    'marginRight',
    'paddingTop',
    'paddingLeft',
    'paddingBottom',
    'paddingRight',
    'lineHeight',
    'textIndent',
    'borderWidth',
    'borderRadius',
    'borderTopWidth',
    'borderBottomWidth',
    'borderLeftWidth',
    'borderRightWidth',
    'borderTopLeftRadius',
    'borderTopRightRadius',
    'borderBottomLeftRadius',
    'borderBottomRightRadius',
  ];
  const obj: Style = {};
  if (styles) {
    Object.keys(styles).forEach((key: string) => {
      if (keys.includes(key) && typeof styles[key] !== 'string') {
        let defaultValue = 0;
        if (key === 'fontSize') {
          defaultValue = 12;
        }
        if (key === 'width' || key === 'height') {
          obj[key] = styles[key] ? `${styles[key]}px` : '';
        } else {
          obj[key] = `${styles[key] ? styles[key] : defaultValue}px`;
        }
      } else {
        obj[key] = styles[key];
      }
    });
  }
  return obj;
};

3.9 颜色格式转换

/**
 * 十六进制颜色转换rgb
 * @param color  十六进制颜色
 */
export function colorRgb(color: string) {
  let sColor = color.toLowerCase();
  // 十六进制颜色值的正则表达式
  const reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/;
  // 如果是16进制颜色
  if (sColor && reg.test(sColor)) {
    if (sColor.length === 4) {
      let sColorNew = '#';
      for (let i = 1; i < 4; i += 1) {
        sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1));
      }
      sColor = sColorNew;
    }
    // 处理六位的颜色值
    const sColorChange: number[] = [];
    for (let i = 1; i < 7; i += 2) {
      // eslint-disable-next-line radix
      sColorChange.push(parseInt(`0x${sColor.slice(i, i + 2)}`));
    }
    return sColorChange.join(',');
  }
  return sColor;
}

/**
 * @description 颜色转成rgba
 * @param color #FFFFFF
 * @param alp 透明度
 * @returns rgba(0,0,0,alp)
 */
export const rgb2rgba = (color: string, alp = 1): string => {
  if (color.indexOf('rgb') !== -1) {
    return color;
  }
  let rgb = '255,255,255';
  // 颜色码对照表
  const colorMap = {
    aliceblue: '#F0F8FF',
    antiquewhite: '#FAEBD7',
    aqua: '#00FFFF',
    aquamarine: '#7FFFD4',
    azure: '#F0FFFF',
    beige: '#F5F5DC',
    bisque: '#FFE4C4',
    black: '#000000',
    blanchedalmond: '#FFEBCD',
    blue: '#0000FF',
    blueviolet: '#8A2BE2',
    brown: '#A52A2A',
    burlywood: '#DEB887',
    cadetblue: '#5F9EA0',
    chartreuse: '#7FFF00',
    chocolate: '#D2691E',
    coral: '#FF7F50',
    cornflowerblue: '#6495ED',
    cornsilk: '#FFF8DC',
    crimson: '#DC143C',
    cyan: '#00FFFF',
    darkblue: '#00008B',
    darkcyan: '#008B8B',
    darkgoldenrod: '#B8860B',
    darkgray: '#A9A9A9',
    darkgreen: '#006400',
    darkkhaki: '#BDB76B',
    darkmagenta: '#8B008B',
    darkolivegreen: '#556B2F',
    darkorange: '#FF8C00',
    darkorchid: '#9932CC',
    darkred: '#8B0000',
    darksalmon: '#E9967A',
    darkseagreen: '#8FBC8F',
    darkslateblue: '#483D8B',
    darkslategray: '#2F4F4F',
    darkturquoise: '#00CED1',
    darkviolet: '#9400D3',
    deeppink: '#FF1493',
    deepskyblue: '#00BFFF',
    dimgray: '#696969',
    dodgerblue: '#1E90FF',
    firebrick: '#B22222',
    floralwhite: '#FFFAF0',
    forestgreen: '#228B22',
    fuchsia: '#FF00FF',
    gainsboro: '#DCDCDC',
    ghostwhite: '#F8F8FF',
    gold: '#FFD700',
    goldenrod: '#DAA520',
    gray: '#808080',
    green: '#008000',
    greenyellow: '#ADFF2F',
    honeydew: '#F0FFF0',
    hotpink: '#FF69B4',
    indianred: '#CD5C5C',
    indigo: '#4B0082',
    ivory: '#FFFFF0',
    khaki: '#F0E68C',
    lavender: '#E6E6FA',
    lavenderblush: '#FFF0F5',
    lawngreen: '#7CFC00',
    lemonchiffon: '#FFFACD',
    lightblue: '#ADD8E6',
    lightcoral: '#F08080',
    lightcyan: '#E0FFFF',
    lightgoldenrodyellow: '#FAFAD2',
    lightgreen: '#90EE90',
    lightgray: '#D3D3D3',
    lightpink: '#FFB6C1',
    lightsalmon: '#FFA07A',
    lightseagreen: '#20B2AA',
    lightskyblue: '#87CEFA',
    lightslategray: '#778899',
    lightsteelblue: '#B0C4DE',
    lightyellow: '#FFFFE0',
    lime: '#00FF00',
    limegreen: '#32CD32',
    linen: '#FAF0E6',
    magenta: '#FF00FF',
    maroon: '#800000',
    mediumaquamarine: '#66CDAA',
    mediumblue: '#0000CD',
    mediumorchid: '#BA55D3',
    mediumpurple: '#9370DB',
    mediumseagreen: '#3CB371',
    mediumslateblue: '#7B68EE',
    mediumspringgreen: '#00FA9A',
    mediumturquoise: '#48D1CC',
    mediumvioletred: '#C71585',
    midnightblue: '#191970',
    mintcream: '#F5FFFA',
    mistyrose: '#FFE4E1',
    moccasin: '#FFE4B5',
    navajowhite: '#FFDEAD',
    navy: '#000080',
    oldlace: '#FDF5E6',
    olive: '#808000',
    olivedrab: '#6B8E23',
    orange: '#FFA500',
    orangered: '#FF4500',
    orchid: '#DA70D6',
    palegoldenrod: '#EEE8AA',
    palegreen: '#98FB98',
    paleturquoise: '#AFEEEE',
    palevioletred: '#DB7093',
    papayawhip: '#FFEFD5',
    peachpuff: '#FFDAB9',
    peru: '#CD853F',
    pink: '#FFC0CB',
    plum: '#DDA0DD',
    powderblue: '#B0E0E6',
    purple: '#800080',
    red: '#FF0000',
    rosybrown: '#BC8F8F',
    royalblue: '#4169E1',
    saddlebrown: '#8B4513',
    salmon: '#FA8072',
    sandybrown: '#FAA460',
    seagreen: '#2E8B57',
    seashell: '#FFF5EE',
    sienna: '#A0522D',
    silver: '#C0C0C0',
    skyblue: '#87CEEB',
    slateblue: '#6A5ACD',
    slategray: '#708090',
    snow: '#FFFAFA',
    springgreen: '#00FF7F',
    steelblue: '#4682B4',
    tan: '#D2B48C',
    teal: '#008080',
    thistle: '#D8BFD8',
    tomato: '#FF6347',
    turquoise: '#40E0D0',
    violet: '#EE82EE',
    wheat: '#F5DEB3',
    white: '#FFFFFF',
    whitesmoke: '#F5F5F5',
    yellow: '#FFFF00',
    yellowgreen: '#9ACD32',
  };
  const colorEncode = Object.keys(colorMap).find((item) => item === color.toLowerCase()); // 颜色码英文名
  rgb = colorEncode ? colorRgb(colorMap[colorEncode]) : colorRgb(color); // rgb
  return `rgba(${rgb},${alp})`;
};

3.10 将数组拆分成指定个数的分组数组

/**
 * @description 将数组拆分
 * @param arr 数组
 * @param n 拆分组数
 * @returns 分组的数组
 */
export const splitArray = (arr: unknown[], n = 1): unknown[] => {
  if (!n) {
    throw new Error(`error in params n: ${n}`);
  }
  const arrTemp: unknown[] = [...arr];
  const every: number = Math.ceil(arrTemp.length / n) || 1;
  const ret: unknown[] = [];
  // eslint-disable-next-line no-constant-condition
  while (true) {
    const temp: unknown[] = arrTemp.splice(0, every);
    if (!temp || temp.length === 0) {
      break;
    }
    ret.push(temp);
  }
  return ret;
};

3.11 生成随机 uuid

export function getUuid(): string {
  const s = [];
  const hexDigits = '0123456789ABCDEF';
  for (let i = 0; i < 32; i += 1) {
    // @ts-ignore
    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  }
  const uuid = s.join('');
  return uuid;
}

3.12 业务方法

3.12.1 获取 AQI 等级

/**
 * 获取AQI值等级
 * @param value aqi数值
 * @returns number AQI等级1-6,7为无数据时
 */
export const getAQILevel = (value: any) => {
  // 数据为null、undefined、NAN、空 无数据,等级7
  if (value === null || value === undefined || Number.isNaN(Number(value)) || value === '') {
    return 7;
  }
  const AQI = Number(value);
  // 0-50 优 等级1
  if (AQI <= 50 && AQI >= 0) {
    return 1;
  }
  // 51-100 良 等级2
  if (AQI > 50 && AQI <= 100) {
    return 2;
  }
  // 101-150 轻度污染 等级3
  if (AQI <= 150 && AQI > 100) {
    return 3;
  }
  // 151-200 中度污染 等级4
  if (AQI <= 200 && AQI > 150) {
    return 4;
  }
  // 201-300 重度污染 等级5
  if (AQI <= 300 && AQI > 200) {
    return 5;
  }
  // 301- 严重污染 等级6
  return 6;
};

3.12.2 获取污染物 html,不存在则原样返回

/**
 * 获取污染物html,不存在则原样返回
 * @param htmlArray 污染物名称对应上下标数组值
 * @param name 污染物名称
 * @return 污染物html
 */
export const getPollutionHtml = (
  htmlArray: { [key: string]: string }[],
  name: string = '',
): string => {
  // 转大写字母,去除._等字符
  const pollutionName: string = name.toUpperCase().replace(/[-.+_]/g, '');
  const maped = htmlArray.filter((item) => item.name === pollutionName);
  if (maped.length > 0) {
    return maped[0].html;
  }
  return name;
};

3.12.3 替换一段字符串中所有污染物为正确格式

/**
 * @description: 替换一段字符串中所有污染物为正确格式
 * @param optionString 要替换的字符串
 * @return 替换完的字符串
 */
export const replacePollutionHtml = (optionString: string): string => {
  let curString = optionString;
  POLLUTION_CHARTS_ALL.forEach((item) => {
    item.name.forEach((name) => {
      curString = curString.replace(name, item.html);
    });
  });
  return curString;
};

4. 创建动态类名

4.1 BEM HELPER

此章节的方法 会根据 元素名、元素状态,来动态生成一个 BEM 风格的类名

假设根类名为 button,button 后会追加块元素、块元素状态,参考下方例子:

b() // 'button'

b('text') // 'button__text'

b({ disabled }) // 'button button--disabled'

b('text', { disabled }) // 'button__text button__text--disabled'

b(['disabled', 'primary']) // 'button button--disabled button--primary'

方法接收两个参数:

  • 元素名:name - 字符串
  • 元素状态:mods - 字符串、对象、数组

方法逻辑:

  • 如果没接收元素状态,则不处理元素名
  • 如果元素状态为字符串,则使用 -- 连接元素名及元素状态
  • 如果元素状态为数组,则递归调用此方法,生成多个类名
  • 如果元素状态为对象,则递归调用此方法,生成多个类名
export type Mod = string | { [key: string]: any };
export type Mods = Mod | Mod[];

/**
 * @description: 动态创建class名称
 * @param name 描述
 * @param mods 状态
 * @return 命名名称
 */
function genBem(name: string, mods?: Mods): string {
  if (!mods) {
    return '';
  }

  if (typeof mods === 'string') {
    return ` ${name}--${mods}`;
  }

  if (Array.isArray(mods)) {
    return mods.reduce<string>((ret, item) => ret + genBem(name, item), '');
  }

  return Object.keys(mods).reduce(
    (ret, key) => ret + (mods[key] ? genBem(name, key) : ''),
    '',
  );
}

export function createBEM(name: string) {
  return (el?: Mods, mods?: Mods): Mods => {
    if (el && typeof el !== 'string') {
      mods = el;
      el = '';
    }
    el = el ? `${name}__${el}` : name;

    return `${el}${genBem(el, mods)}`;
  };
}

export type BEM = ReturnType<typeof createBEM>;

4.2 创建命名空间

/**
 * @description: 创建命名空间
 * @param name 名称
 * @return 新名词
 */
export function createNamespace(name: string) {
  const prefixedName = `t-${name}`;
  return [createBEM(prefixedName)] as const;
}

5. 获取并设置 cookies 中的语言类型

import Cookies from 'js-cookie';
const CookieKeys = {
  // 语言类型
  LANGUAGE_KEY: 'language',
};

/**
 * 获取语言类型
 */
export const getLanguage = () => Cookies.get(CookieKeys.LANGUAGE_KEY);

/**
 * 设置语言类型
 * @param language
 */
export const setLanguage = (language: string) => Cookies.set(CookieKeys.LANGUAGE_KEY, language);

6. 主题换肤处理

6.1 修改主题色及背景色

Array.from ()方法详解_一晌贪欢i的博客-CSDN博客_array.fromArray.from()方法就是将一个类数组对象或者可遍历对象转换成一个真正的数组,也是ES6的新增方法。那么什么是类数组对象呢?所谓类数组对象,最基本的要求就是具有length属性的对象。1、将类数组对象转换为真正数组:let arrayLike = { 0: 'tom', 1: '65', 2: '男', 3: ['jane','john','Mary'], 'length': 4}let arr = Array.from(arrayLhttps://blog.csdn.net/qq_27674439/article/details/108793223

使用 setProperty 调整属性值

/**
 * 修改主题色及背景色
 * @param className
 * @param themeColor
 * @param backgroundColor
 */
export function changeThemeStyle(className: string, themeColor: string, backgroundColor: string) {
  const themeElement: Array<HTMLElement> = Array.from(document.querySelectorAll(className));
  if (themeElement && themeElement.length) {
    themeElement.forEach((item: HTMLElement) => {
      // 修改深浅主题元素的主题色
      item.style.setProperty('--theme-color', themeColor);
      // 修改深浅主题元素的背景色
      item.style.setProperty('--background-color', backgroundColor);
    });
  }
}

6.2 设置颜色变量值

使用 setProperty 调整属性值

/**
 * 设置颜色变量值
 * @param className 元素类名
 * @param variableName 变量名称
 * @param value 变量值
 */
export function setColorVariable(className: string, variableName: string, value: string) {
  const themeElement: Array<HTMLElement> = Array.from(document.querySelectorAll(className));
  if (themeElement && themeElement.length) {
    themeElement.forEach((item: HTMLElement) => {
      // 修改变量值
      item.style.setProperty(variableName, value);
    });
  }
}

6.3 修改主题风格下的颜色变量

提前内置 light、dark 两套主题

/**
 * 修改主题风格下的颜色变量
 */
export function changeColorVariable() {
  interface IThemeVariables {
    [propName: string]: {
      [propName: string]: string;
    };
  }
  const variables: IThemeVariables = {
    '.light': {
      /* 主题色 默认为primary */
      '--theme-color': 'var(--t-brand8)',
      '--theme-color-opacity-10': 'rgba(0, 82, 217, 0.1)',
      '--theme-color-opacity-15': 'rgba(0, 82, 217, 0.15)',
      '--theme-color-opacity-30': 'rgba(0, 82, 217, 0.3)',
      '--theme-color-opacity-60': 'rgba(0, 82, 217, 0.6)',
      '--theme-color-opacity-80': 'rgba(0, 82, 217, 0.8)',
      '--theme-color-opacity-90': 'rgba(0, 82, 217, 0.9)',

      /* 颜色变量 */
      '--t-font-color1': '#333',
      '--t-font-color2': '#333',
      '--t-font-color3': '#666',
      '--t-font-color4': '#999',
      '--t-border-color3': '#DEDEDE',
      '--t-border-color2': '#D8D8D8',
      '--t-border-color1': '#999',
      '--t-background-color1': '#FFF',
      '--t-background-color2': '#333',
      '--t-background-color3': '#999',
      '--t-background-color4': '#F3F3F3',
      '--t-background-color': '#FFF',
      '--t-background-color-dark': '#000050',

      /** 菜单下划线颜色 * */
      '--t-border-bottom-color': 'var(--theme-color)',

      /** 菜单下划线颜色 * */
      '--t-surface-background-color': 'var(--theme-color)',

      /* 背景色 */
      '--background-color': '#FFF',
      '--background-color-dark': '#000050',

      /* 基础字号 用于整体动态改变字号使用 */
      '--base-font-size': '16px',

      /* border-radius 用于整体动态改变border-radius使用 */
      '--border-radius-base': '4px',
      '--border-radius-small': '2px',

      /* padding */
      '--t-padding-md': '20px',
      '--t-padding-xs': '10px',
    },
    '.dark': {
      /* 主题色 默认为primary */
      '--theme-color': '#0DE0E8',
      '--theme-color-opacity-10': 'rgba(13, 224, 232, 0.1)',
      '--theme-color-opacity-15': 'rgba(13, 224, 232, 0.15)',
      '--theme-color-opacity-30': 'rgba(13, 224, 232, 0.3)',
      '--theme-color-opacity-60': 'rgba(13, 224, 232, 0.6)',
      '--theme-color-opacity-80': 'rgba(13, 224, 232, 0.8)',
      '--theme-color-opacity-90': 'rgba(13, 224, 232, 0.9)',

      /* 颜色变量 */
      '--t-font-color1': '#333',
      '--t-font-color2': '#333',
      '--t-font-color3': '#666',
      '--t-font-color4': '#999',
      '--t-border-color3': '#DEDEDE',
      '--t-border-color2': '#D8D8D8',
      '--t-border-color1': '#999',
      '--t-background-color1': '#FFF',
      '--t-background-color2': '#333',
      '--t-background-color3': '#999',
      '--t-background-color4': '#F3F3F3',
      '--t-background-color': '#FFF',
      '--t-background-color-dark': '#000050',

      /** 菜单下划线颜色 * */
      '--t-border-bottom-color': 'var(--theme-color)',

      /** 菜单下划线颜色 * */
      '--t-surface-background-color': 'var(--theme-color)',

      /* 背景色 */
      '--background-color': '#FFF',
      '--background-color-dark': '#000050',

      /* 基础字号 用于整体动态改变字号使用 */
      '--base-font-size': '16px',

      /* border-radius 用于整体动态改变border-radius使用 */
      '--border-radius-base': '4px',
      '--border-radius-small': '2px',

      /* padding */
      '--t-padding-md': '20px',
      '--t-padding-xs': '10px',
    },
  };
  Object.keys(variables).forEach((key: string) => {
    Object.keys(variables[key]).forEach((variableName: string) => {
      setColorVariable(key, variableName, variables[key][variableName]);
    });
  });
}

6.4 设置主题及背景色、设置主题风格下的颜色变量

/**
 * 设置主题色及背景色
 */
export function useSetThemeStyle() {
  /**
   * 设置主题色
   */
  function setThemeStyle() {
    changeThemeStyle('.dark', '#0de0e8', '#000050');
    changeThemeStyle('.light', '#33B897', '#fff');
  }

  /**
   * 设置主题风格下的颜色变量
   */
  function setColorVariables() {
    changeColorVariable();
  }
  return {
    setThemeStyle,
    setColorVariables,
  };
}

6.5 将设置主题色及颜色变量的方法封装为 hooks

import { useSetThemeStyle } from './theme';

export default {
  /**
   * 初始化主题色及背景色
   */
  mounted() {
    const { setColorVariables } = useSetThemeStyle();
    setColorVariables();
  },
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lyrelion

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值