Categories
Vue

vue-i18n — Formatting Text and Numbers

Spread the love

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at how to create multilingual Vue apps with vue-i18n.

Localizing Numbers

We can display numbers in the locale we want with vue-i18n.

To do that, we add the format that we want:

import Vue from "vue";
import App from "./App.vue";
import VueI18n from "vue-i18n";

Vue.use(VueI18n);
Vue.config.productionTip = false;

const numberFormats = {
  "en-ca": {
    currency: {
      style: "currency",
      currency: "CAD"
    }
  },
  fr: {
    currency: {
      style: "currency",
      currency: "EUR",
      currencyDisplay: "symbol"
    }
  }
};

const i18n = new VueI18n({
  numberFormats
});

new Vue({
  i18n,
  render: h => h(App)
}).$mount("#app");

We add the number style with the style property.

currency tells us what currency it is, and currencyDisplay tells how to display tjhe currency value.

Then we can use the $n function in our component:

<template>
  <div id="app">
    <p>{{ $n(100, 'currency', 'fr') }}</p>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

to format the number.

Now we get:

100,00 €

on the screen.

Custom Formatting

We can format currencies our way.

The i18n-n component lets us format currencies.

For instance, we can write:

<template>
  <div id="app">
    <i18n-n :value="100" format="currency" locale="fr"></i18n-n>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

value has the currency value. format tells us how to format the number.

locale is the locale.

The component also accepts content in its slots for more customization.

We can add content to the currency slot to format it as a currency:

<template>
  <div id="app">
    <i18n-n :value="100" format="currency" locale="fr">
      <template v-slot:currency="{ currency }">
        <span style="color: red">{{ currency }}</span>
      </template>
    </i18n-n>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

We populate the currency slot with our own content.

We add a span into the slot and styled it red.

Now the currency symbol is red.

There’s also an integer slot for the integer part of the number.

group slot has the thousands group.

fraction slot has the fractional part.

Locale Messages Syntax

We can add locale messages in various ways.

For instance, we can write:

import Vue from "vue";
import App from "./App.vue";
import VueI18n from "vue-i18n";

Vue.use(VueI18n);
Vue.config.productionTip = false;

const messages = {
  en: {
    foo: "foo",
    nested: {
      message: "bar"
    },
    messages: [
      "baz",
      {
        internal: "internal message"
      },
      ["qux"]
    ]
  },
  fr: {
    //...
  }
};

const i18n = new VueI18n({
  messages,
  locale: "en"
});

new Vue({
  i18n,
  render: h => h(App)
}).$mount("#app");

then we can write:

<template>
  <div id="app">
    <p>{{ $t('foo') }}</p>
    <p>{{ $t('nested.message') }}</p>
    <p>{{ $t('messages[0]') }}</p>
    <p>{{ $t('messages[1].internal') }}</p>
    <p>{{ $t('messages[2][0]') }}</p>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

in our component.

We can have messages in objects, arrays, and we can get them by their usual path with $t .

So we have:

foo

bar

baz

internal message

qux

displayed on the screen.

Linked Locale Messages

Locale messages can also reference other locale messages.

We can do that with @: .

For instance, we can write:

main.js

import Vue from "vue";
import App from "./App.vue";
import VueI18n from "vue-i18n";

Vue.use(VueI18n);
Vue.config.productionTip = false;

const messages = {
  en: {
    foo: "foo",
    foobar: "@:foo bar"
  },
  fr: {}
};

const i18n = new VueI18n({
  messages,
  locale: "en"
});

new Vue({
  i18n,
  render: h => h(App)
}).$mount("#app");

App.vue

<template>
  <div id="app">
    <p>{{ $t('foo') }}</p>
    <p>{{ $t('foobar') }}</p>
  </div>
</template>

<script>
export default {
  name: "App"
};
</script>

The @: symbol indicates that we match the message with the key that comes after it.

We can also format the linked messages.

The modifiers can be upper , lower , and capitalize .

For instance, we can write:

import Vue from "vue";
import App from "./App.vue";
import VueI18n from "vue-i18n";

Vue.use(VueI18n);
Vue.config.productionTip = false;

const messages = {
  en: {
    foo: "foo",
    foobar: "@.upper:foo bar"
  },
  fr: {}
};

const i18n = new VueI18n({
  messages,
  locale: "en"
});

new Vue({
  i18n,
  render: h => h(App)
}).$mount("#app");

to make 'foo' upper case.

Now we get:

foo

FOO bar

displayed on the screen.

Conclusion

There are many ways to format numbers and locale strings with vue-i18n.

Messages can reference other messages. Numbers can be formatted as currencies.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *