[Day06] Vue i18n - Number Formatting (Currency 货币)

在本地化 (localize) 专案时,我们可能会遇到需要处理金钱、价钱等货币的问题,在显示价钱时我们会需要依据当前的语系显示相对应的货币符号 ,例如:

<p>NT$10,000</p> // 台币
<p>$10,000</p>   // 美金
<p>¥10,000</p>  // 日币

所以今天我们要来分享的就是可以帮我们达到这件事的 Number Formatting,事实上 Number Formatting 除了货币以外,它也可以处理纯数字格式 (decimal)、百分比 (percent) 以及物理单位 (unit) 在不同语系的显示,因为它背後的运作原理就是透过 JS 原生的 Intl.NumberFormat 来做到的,不过我们今天的重点只会在货币的部分。

配置属性选项

export default createI18n({
 ...,
 numberFormats: {
  en: {
    currency: {
      style: 'currency',
      currency: 'USD',
      currencyDisplay: 'symbol',
      minimumFractionDigits: 0,
      maximumFractionDigits: 0,
      useGrouping: true
    }
  },
})

style 要使用的格式样式,预设会是 decimal

  • currency : 货币格式。
  • decimal: 纯十进制的数字格式。
  • percent: 百分比格式。
  • unit: 单位格式 (物理)。

currency 指定使用哪一种国际货币,常见的台币 TWD, 美金 USD,详细的完整列表可以参考 ISO 4217

currencyDisplay 以哪种方式显示显示货币。

  • symbol: 当地的货币符号,例如 NT$123,456。
  • narrowSymbol : 当地的窄格式货币符号,例如 $123,456。
  • code : ISO currency code,例如 TWD 123,456。
  • name : 当地的货币名称,例如 123,456.79 新台币。

minimumFractionDigits 最小的小数位数,可接受 0 到 20。

maximumFractionDigits 最大的小数位数,可接受 0 到 20,不过不能小於 minimumFractionDigits 。

useGrouping 是否使用分组分隔符,例如千/十万/千万分隔符。

事实上不同的 style 或多或少会有不同的属性可以配置,不过这里我们就只针对货币常使用的属性做介绍,详细完整的可参考 Intl.NumberFormat() constructor

基本用法

number formatting 所使用的 translation api 是 $n(value, key, locale)

  • value - 要本地化的数值。
  • key - 这边的 key 指是 en 下一层的 currency,这是自己定义的,不是因为 style 是 currency,因此我们也可以定义好几个格式。
  • locale - 指定要用哪一个语系来本地化,预设会是全局的 locale 值。
export default createI18n({
 ...,
 numberFormats: {
  en: {
    currency: {
      style: 'currency',
      currency: 'USD'
    },
    currencyNoGroup: {
      style: 'currency',
      currency: 'USD',
      minimumFractionDigits: 0,
      maximumFractionDigits: 0,
      useGrouping: false
    }
  },
})

所以在 template 的写法会是:

<p>{{ $n(10000, 'currency') }}</p>
<p>{{ $n(10000, 'currencyNoGroup') }}</p>

得到的结果是:

<p>$10,000.00</p>
<p>$10000</p>

Custom Formatting

由於 $n 会直接回传格式化的字串结果,我们只能作为一整体去使用,但有的时候我们会需要针对其中一部分去设定不同的样式,例如下图中货币符号和数值的大小不同,所以为了应对这种情况 vue i18n 有提供我们 NumberFormat 组件 (i18n-n) 来达到这件事。(有点像是我昨天介绍的 Component Interpolation)

https://ithelp.ithome.com.tw/upload/images/20210921/20113487Xs190AbzQb.png

i18n-n 的基本用法如下。 (此时得到的结果和用 $n 的结果一样)

<i18n-n tag="span" :value="100" format="currency" locale="en"></i18n-n>

i18n-n 有四个 props :

tag 选择根节点的 HTML tag。

value 要本地化的数值。

format 选用哪一个定义好的格式的 key (同 $n(value, key) 中的 key)。

locale 指定要用哪一个语系来本地化,预设会是全局的 locale 值。

如果想要个别控制每一个部分做到上面图示中的样子,我们要透过 slots 的方式,像是:

<i18n-n tag="span" :value="1000" format="currency">
  <template #currency="slotProps">
    <span class="currency">{{ slotProps.currency }}</span>
  </template>
  <template #integer="slotProps">
    <span class="integer">{{ slotProps.integer }}</span>
  </template>
  <template #group="slotProps">
    <span class="group">{{ slotProps.group }}</span>
  </template>
  <template #fraction="slotProps">
    <span class="fraction">{{ slotProps.fraction }}</span>
  </template>
  <template #decimal="slotProps">
    <span class="decimal">{{ slotProps.decimal }}</span>
  </template>
</i18n-n>

这样得到的结果会是

// $1,000.00
<span>
  <span class="currency">$</span>
  <span class="integer">1</span>
  <span class="group">,</span>
  <span class="integer">000</span>
  <span class="decimal">.</span>
  <span class="fraction">00</span>
</span>

参考资料


今天的分享就到这边,如果大家对我分享的内容有兴趣欢迎点击追踪 & 订阅系列文章,如果对内容有任何疑问,或是文章内容有错误,都非常欢迎留言讨论或指教的!

明天要来分享的是 Vue i18n 主题的最後一篇 Datetime Formatting,那我们明天见!


<<:  【在 iOS 开发路上的大小事-Day09】将常用的 Function 写成一个 class,让各个档案都能使用

>>:  NNI安装在本机(Windows版)

Day11-Go映射map

前言 前面我们介绍了几种变数容器,例如阵列和切片,这些皆以数字做为索引,而今天要介绍的映射(map)...

Day 26 bert 文字情感分类-5

训练时间约半个小时,但 colab 的速度并不稳定,以前也有同一笔资料训练4个小时的状况。 根据20...

Golang - debug工具 DELVE

状况 最近的经验是要把公司的程序码翻新 但由於旧有的程序码技术债实在太过庞大,没办法像以前以往接手到...

[Day5] 和应用程序有关的攻击-例外处理,重播攻击,请求伪造

今天继续更新和应用程序有关的攻击方式。 例外处理 例外处理是指软硬体在执行程序的过程中发生非预期状况...

曝露系数(Exposure factor)

-简单的定量风险分析 曝露系数 (EF) 曝露系数 (EF) 是在实现特定威胁时对特定资产的主观、...