Skip to content

Number Formatting

Basic Usage

You can localize a number with your defined formats.

The numeric formats are as follows:

js
const numberFormats = {
  'en-US': {
    currency: {
      style: 'currency', currency: 'USD', notation: 'standard'
    },
    decimal: {
      style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2
    },
    percent: {
      style: 'percent', useGrouping: false
    }
  },
  'ja-JP': {
    currency: {
      style: 'currency', currency: 'JPY', useGrouping: true, currencyDisplay: 'symbol'
    },
    decimal: {
      style: 'decimal', minimumSignificantDigits: 3, maximumSignificantDigits: 5
    },
    percent: {
      style: 'percent', useGrouping: false
    }
  }
}

As indicated above, you can define named numeric formats (e.g., currency, etc.), and you should use the ECMA-402 Intl.NumberFormat options

After this, when using localized messages, you need to specify the numberFormats option of createI18n:

js
const i18n = createI18n({
  numberFormats
})

To localize a numeric value with Vue I18n, use $n.

TIP

$n has several overloads. For details about these overloads, see the API Reference

The following example shows how to use $n in a template:

html
<p>{{ $n(10000, 'currency') }}</p>
<p>{{ $n(10000, 'currency', 'ja-JP') }}</p>
<p>{{ $n(10000, 'currency', 'ja-JP', { useGrouping: false }) }}</p>
<p>{{ $n(987654321, 'currency', { notation: 'compact' }) }}</p>
<p>{{ $n(0.99123, 'percent') }}</p>
<p>{{ $n(0.99123, 'percent', { minimumFractionDigits: 2 }) }}</p>
<p>{{ $n(12.11612345, 'decimal') }}</p>
<p>{{ $n(12145281111, 'decimal', 'ja-JP') }}</p>

The first argument is the numeric value as a parameter, the second argument is the name of the numeric format as a parameter. The last argument is the locale value as a parameter.

The result is as follows:

html
<p>$10,000.00</p>
<p>¥10,000</p>
<p>¥10000</p>
<p>$988M</p>
<p>99%</p>
<p>99.12%</p>
<p>12.12</p>
<p>12,145,000,000</p>

Custom Formatting

$n returns a fully formatted string with a number, which can only be used in its entirety. In scenarios where you need to format specific parts of a formatted number (such as fractional digits), $n is insufficient. In this case, the NumberFormat component (i18n-n) will be helpful.

With a minimal set of properties, i18n-n generates the same result as $n, encapsulated within a configured DOM element.

The following template:

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

The NumberFormat component has multiple props.

The tag property allows you to define the tag.

The value property allows you to define the numeric value to format.

The format property is the property to which the format defined by the numberFormats option of createI18n can be applied.

The locale property allows you to define the locale. It is localized with the locale specified by this prop rather than the one specified by the locale option of createI18n.

This will generate the following output:

html
<span>100</span>
<span>$100.00</span>
<span>¥100</span>

But the real power of this component becomes evident when it is used with scoped slots.

Say there is a need to render the integer part of the number with a bolder font. This can be achieved by specifying the scoped slot element integer:

html
<i18n-n tag="span" :value="100" format="currency">
  <template #integer="slotProps">
    <span style="font-weight: bold">{{ slotProps.integer }}</span>
  </template>
</i18n-n>

The above template will produce the following HTML:

html
<span>$<span style="font-weight: bold">100</span>.00</span>

It is possible to specify multiple scoped slots simultaneously:

html
<i18n-n tag="span" :value="1234" :format="{ key: 'currency', currency: 'EUR' }">
  <template #currency="slotProps">
    <span style="color: green">{{ slotProps.currency }}</span>
  </template>
  <template #integer="slotProps">
    <span style="font-weight: bold">{{ slotProps.integer }}</span>
  </template>
  <template #group="slotProps">
    <span style="font-weight: bold">{{ slotProps.group }}</span>
  </template>
  <template #fraction="slotProps">
    <span style="font-size: small">{{ slotProps.fraction }}</span>
  </template>
</i18n-n>

(The generated HTML has been formatted for better readability)

html
<span>
  <span style="color: green">€</span>
  <span style="font-weight: bold">1</span>
  <span style="font-weight: bold">,</span>
  <span style="font-weight: bold">234</span>
  .
  <span style="font-size: small">00</span>
</span>

NOTE

A complete list of supported scoped slots and other properties of i18n-n can be found in the API Reference

Scope Resolution

The scope resolution of the NumberFormat component is the same as the Translation component.

See here