单位转换 3.x
单位转换用于将数值从一个单位换算到另一个单位(如分→元、米→千米、华氏度→摄氏度等)。
配置方式
单位转换配置需要通过 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/div → plus/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 按以下顺序匹配输入单位:
语法显式指定(最高优先级)
javascriptcalc('100 | !ua:元:厘') // 使用"厘"_unit_default_in配置javascriptset_config({ _unit_default_in: '分' }) calc('100 | !ua:元') // 使用"分"单一输入单位(自动使用)
javascriptset_config({ _unit_convert_out: { '元': { '分': 0.01 } } // 只有"分" }) calc('100 | !ua:元') // 自动使用"分"多个输入单位且无法确定:不进行转换
@ 变量引用
使用 @ 前缀在单位语法中引用变量值:
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_out | object | 单位转换映射(输出单位为 key) | ✅ |
_unit_convert_in | object | 单位转换映射(输入单位为 key) | ✅ |
_unit_default_out | string | string[] | 默认输出单位 | ✅ |
_unit_default_in | string | string[] | 默认输入单位 | ✅ |
_unit_default_position | string | 默认单位位置 | ✅ |
_unit_position_map | object | 单位到位置的映射 | ✅ |
_unit_thousands_map | object | 单位到千分位预设的映射 | ✅ |
_unit_compact_map | object | 单位到紧凑格式预设的映射 | ✅ |
| 格式语法 | 说明 |
|---|---|
!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'