Skip to content

单位转换 3.x

单位转换用于将数值从一个单位换算到另一个单位(如分→元、米→千米、华氏度→摄氏度等)。

基础单位计算

如果只需要基础的单位计算(如 100元 + 50元),使用 _unit: true 即可。

详见 单位计算

配置方式

单位转换配置需要通过 set_config 设置为全局配置。

为什么只支持全局配置?

单位转换规则通常是全局性的(如货币汇率、单位换算关系),在整个应用中保持一致。如果需要在特殊场景使用不同配置,可以通过切换全局配置来实现。

全局配置

使用 set_config 设置全局配置:

javascript
import { calc, set_config, reset_config } from 'a-calc'

// 设置全局单位转换配置
set_config({
  _unit_convert_out: {
    '元': { '分': 0.01 },
    '$': { '¢': 0.01 }
  },
  _unit_default_out: '元',
  _unit_default_in: '分',
  _unit_default_position: 'after'
})

// 之后的调用无需再传入配置
calc('100 | =2 !ua:元')  // '1.00元'
calc('200 | =2 !ua:元')  // '2.00元'

// 重置配置
reset_config()  // 重置所有
reset_config('_unit_convert_out')  // 重置单个

切换配置

如果需要在不同场景使用不同配置,可以动态切换:

javascript
// 场景1:中国区配置
set_config({
  _unit_convert_out: { '元': { '分': 0.01 } }
})
calc('100 | =2 !ua:元')  // '1.00元'

// 场景2:美国区配置
set_config({
  _unit_convert_out: { '$': { '¢': 0.01 } }
})
calc('100 | =2 !ua:$')  // '1.00$'

基本用法

_unit_convert_out(推荐)

输出单位为 key 配置转换规则:

javascript
set_config({
  _unit_convert_out: {
    '元': { '分': 0.01 }  // 分 × 0.01 = 元
  }
})

calc('100 | =2 !ua:元')  // '1.00元' (100分 → 1元)

_unit_convert_in

输入单位为 key 配置转换规则(会自动转换为 _unit_convert_out 格式):

javascript
set_config({
  _unit_convert_in: {
    '分': { '元': 0.01 }
  }
})

calc('100 | =2 !ua:元')  // '1.00元'

推荐使用 _unit_convert_out

_unit_convert_out 以输出单位为 key,查找时间复杂度为 O(1),性能更优。

语法方式

基本语法

在格式字符串中直接指定转换:

javascript
set_config({
  _unit_convert_out: { 
    '元': { '分': 0.01, '厘': 0.001 } 
  }
})

// 只指定输出单位(自动查找输入单位)
calc('100 | =2 !ua:元')  // '1.00元'

// 同时指定输出和输入单位
calc('100 | =2 !ua:元:分')  // '1.00元'

// 只转换不显示单位
calc('100 | =2 !uh:元')  // '1.00'

不带参数使用(使用默认单位)

!ua!ub!um 可以不带参数单独使用,此时会使用 _unit_default_out 配置的默认输出单位:

javascript
set_config({
  _unit_convert_out: { 
    '元': { '分': 0.01 } 
  },
  _unit_default_out: '元'  // 设置默认输出单位
})

// 不带参数,使用默认单位
calc('10000 | =2 !ua')   // '100.00元' (使用默认单位 '元')
calc('10000 | =2 !ub')   // '元100.00' (单位在前)
calc('-10000 | + !um')   // '-元100' (单位在中间)

// 带参数,使用指定单位(优先级更高)
calc('10000 | =2 !ua:$')  // '10000.00$' (使用指定单位,不进行转换)

使用场景

  • 在分组中定义格式时,可以省略单位参数
  • 在全局配置了默认单位后,简化格式化代码
  • 配合 _unit_default_out 数组,支持多个默认单位
javascript
// 配合分组使用
set_config({
  _unit_convert_out: { '元': { '分': 0.01 } },
  _unit_default_out: '元',
  _fmt_groups: {
    'price': '=2, !ua'  // 不需要指定单位
  }
})

calc('10000 | #price')  // '100.00元'

转换规则格式

转换规则支持多种格式:

javascript
set_config({
  _unit_convert_out: {
    '元': {
      // 1. 数字:直接作为乘数
      '分': 0.01,  // value × 0.01

      // 2. 对象 mul:乘以指定值
      '角': { mul: 0.1 },  // value × 0.1

      // 3. 对象 div:除以指定值
      '厘': { div: 1000 },  // value ÷ 1000

      // 4. 对象组合:mul/div → plus/minus
      '特殊': {
        mul: 0.01,   // 先乘
        plus: 1      // 再加
      },

      // 5. 函数:完全自定义
      'CNY': (value, inputUnit, outputUnit) => value / 7.2,

      // 6. 对象 fn:自定义函数
      'USD': {
        fn: (value, inputUnit, outputUnit) => value / 7.2
      }
    }
  }
})

对象规则执行顺序mul/divplus/minus

javascript
// 例:华氏度转摄氏度 C = (F - 32) × 5/9
// 对象形式无法正确表达(顺序不对),使用函数
set_config({
  _unit_convert_out: {
    '℃': {
      '℉': (f) => (f - 32) * 5 / 9
    }
  }
})

纯配置模式

不使用语法参数,完全通过配置项控制转换。这种方式特别适合与 !ua!ub!um 不带参数的语法配合使用:

javascript
set_config({
  _unit_convert_out: { '元': { '分': 0.01 } },
  _unit_default_out: '元',           // 默认输出单位
  _unit_default_in: '分',            // 默认输入单位
  _unit_default_position: 'after'    // 单位位置
})

// 方式1:完全不使用格式化语法
calc('100 | =2')        // '1.00元' (使用所有默认配置)

// 方式2:使用 !ua/!ub/!um 但不带参数
calc('100 | =2 !ua')    // '1.00元' (使用默认单位)
calc('100 | =2 !ub')    // '元1.00' (单位在前)
calc('-100 | + !um')    // '-元1' (单位在中间)

优势

  • 代码更简洁,格式化字符串不需要重复写单位
  • 便于统一管理单位配置
  • 适合在分组中使用
javascript
// 配合分组使用
set_config({
  _unit_convert_out: { '元': { '分': 0.01 } },
  _unit_default_out: '元',
  _fmt_groups: {
    'price': '=2, !ua',      // 不需要指定单位
    'amount': '=2,+ !ub'     // 不需要指定单位
  }
})

calc('10000 | #price')   // '100.00元'
calc('10000 | #amount')  // '+元100.00'

多输入单位选择

当一个输出单位对应多个输入单位时,使用 _unit_default_in 指定默认输入单位:

javascript
// 元可以从"分"或"厘"转换
set_config({
  _unit_convert_out: { '元': { '分': 0.01, '厘': 0.001 } },
  _unit_default_in: '分'  // 默认从"分"转换
})

calc('100 | =2 !ua:元')  // '1.00元' (100分 → 1元)

// 切换默认输入单位
set_config({
  _unit_convert_out: { '元': { '分': 0.01, '厘': 0.001 } },
  _unit_default_in: '厘'  // 默认从"厘"转换
})

calc('100 | =3 !ua:元')  // '0.100元' (100厘 → 0.1元)

// 可以是数组,按顺序优先匹配
set_config({
  _unit_convert_out: { '元': { '分': 0.01, '厘': 0.001 } },
  _unit_default_in: ['分', '厘']  // 优先"分"
})

calc('100 | =2 !ua:元')  // '1.00元'

智能匹配优先级

当只指定输出单位时,a-calc 按以下顺序匹配输入单位:

  1. 语法显式指定(最高优先级)

    javascript
    calc('100 | !ua:元:厘')  // 使用"厘"
  2. _unit_default_in 配置

    javascript
    set_config({ _unit_default_in: '分' })
    calc('100 | !ua:元')  // 使用"分"
  3. 单一输入单位(自动使用)

    javascript
    set_config({
      _unit_convert_out: { '元': { '分': 0.01 } }  // 只有"分"
    })
    calc('100 | !ua:元')  // 自动使用"分"
  4. 多个输入单位且无法确定:不进行转换

@ 变量引用

使用 @ 前缀在单位语法中引用变量值:

javascript
set_config({
  _unit_convert_out: { '元': { '分': 0.01, '厘': 0.001 } }
})

// 基础引用
calc('100 | !ua:@unit', { unit: '元' })    // '100元'

// 变量路径
calc('100 | !ua:@config.unit', {
  config: { unit: '元' }
})  // '100元'

// 结合转换
calc('100 | =2 !ua:@outUnit', {
  outUnit: '元'
})  // '1.00元'

// 同时指定输入输出单位
calc('100 | =2 !ua:@outUnit:@inUnit', {
  outUnit: '元',
  inUnit: '分'
})  // '1.00元'

配置项速查

所有配置项都需要通过 set_config 设置为全局配置。

配置项类型说明支持全局
_unit_convert_outobject单位转换映射(输出单位为 key)
_unit_convert_inobject单位转换映射(输入单位为 key)
_unit_default_outstring | string[]默认输出单位
_unit_default_instring | string[]默认输入单位
_unit_default_positionstring默认单位位置
_unit_position_mapobject单位到位置的映射
_unit_thousands_mapobject单位到千分位预设的映射
_unit_compact_mapobject单位到紧凑格式预设的映射
格式语法说明
!u去除单位(等同于 !uh
!u:output显示单位(位置可配置)
!ua:output转换并显示单位在后
!ub:output转换并显示单位在前
!um:output转换并显示单位在中间
!uh:output只转换不显示单位
!ua:output:input指定输入输出单位
!ua:@var使用变量值作为单位
!ua不带参数,使用 _unit_default_out 配置的默认单位
!ub不带参数,使用默认单位(单位在前)
!um不带参数,使用默认单位(单位在中间)

完整示例

货币分转元

javascript
set_config({
  _unit_convert_out: {
    '元': { '分': 0.01 }
  }
})

calc('12345 | =2 !ua:元')    // '123.45元'
calc('12345 | =2, !ua:元')   // '123.45元'

多货币系统

javascript
set_config({
  _unit_convert_out: {
    '元': { '分': 0.01, '厘': 0.001 },
    '$': { '¢': 0.01 },
    '€': { 'cent': 0.01 }
  },
  _unit_default_in: ['分', '¢', 'cent']
})

calc('12345 | =2 !ua:元')  // '123.45元'
calc('12345 | =2 !ub:$')   // '$123.45'
calc('12345 | =2 !ub:€')   // '€123.45'

长度单位换算

javascript
set_config({
  _unit_convert_out: {
    '千米': {
      '米': { div: 1000 },
      '厘米': { div: 100000 }
    },
    '米': {
      '厘米': { div: 100 },
      '毫米': { div: 1000 }
    }
  }
})

calc('5000 | =2 !ua:千米:米')    // '5.00千米'
calc('150 | =2 !ua:米:厘米')     // '1.50米'

温度转换

javascript
set_config({
  _unit_convert_out: {
    '℃': {
      '℉': (f) => (f - 32) * 5 / 9,
      'K': (k) => k - 273.15
    },
    '℉': {
      '℃': (c) => c * 9 / 5 + 32
    }
  }
})

calc('100 | =1 !ua:℃:℉')   // '37.7℃' (100℉ → 37.7℃)
calc('0 | =1 !ua:℃:K')     // '-273.1℃' (0K → -273.15℃)
calc('37.7 | =1 !ua:℉:℃')  // '99.8℉' (37.7℃ → 99.86℉)

存储单位

javascript
set_config({
  _unit_convert_out: {
    'GB': {
      'MB': { div: 1024 },
      'KB': { div: 1024 * 1024 },
      'B': { div: 1024 * 1024 * 1024 }
    },
    'MB': {
      'KB': { div: 1024 },
      'B': { div: 1024 * 1024 }
    }
  }
})

calc('2048 | =2 !ua:GB:MB')  // '2.00GB'
calc('1536 | =2 !ua:MB:KB')  // '1.50MB'

基于 MIT 许可发布