By yugasun from yugasun.com/post/you-ma… This article can be reproduced in full, but the original author and source need to be retained.

Vue-i18n is the perfect choice for internationalization. It is very simple to use, but it also brings some problems and challenges. This article is a summary of some personal experiences in the internationalization of projects, hoping to help you on the road to internationalization.

The basic use

Create i18n instance in SRC /lang directory index.js, zh.js, and en.js respectively. Then create i18n instance in index.js and export it for vue.

import Vue from 'vue';
import VueI18n from 'vue-i18n';

import zhMsg from './zh';
import enMsg from './en';

Vue.use(VueI18n);

const messages = {
  zh: {
    ...zhMsg,
  },
  en: {
    ...enMsg,
  },
};

const i18n = new VueI18n({
  locale: 'zh',
  messages,
});

export default i18n;
Copy the code

Then write the language package file:

// zh.js
export default {
  index: {
    header: {
      title: 'the Vue - I18n sample'.subtitle: 'You will learn how to use vuE-i18n',}}};// en.js
export default {
  index: {
    header: {
      title: 'Vue-I18n Demo'.subtitle: 'You will learn how to use vue-i18n',}}};Copy the code

Next in the entry file SRC /main.js:

// ...
import i18n from './lang';

// ...
new Vue({
  i18n,
  router,
  el: '#app'.template: '<App/>'.components: { App },
});
Copy the code

SRC /views/index.vue; SRC /views/index.vue;

<h1>{{ $t('index.header.title') }} </h1>
<h3>{{ $t('index.header.subtitle') }} </h3>
Copy the code

Doesn’t it seem simple enough, when vue-i18n is introduced, it will mount the internationalized API it provides on the vue instance, such as $t, $TC, $TD and other formatting functions. We just need to call it directly from the component, for example: this.$t.

$t takes two arguments. The first is the path to the attributes we access in the language package. For example, if we changed the template for index.header.subtitle to You will learn how to use {name}, we could use it like this:

$t('index.header.subtitle', {name: 'vue-i18n})
Copy the code

tip

Gets a collection of key values

I believe that you already know how to use VUE-I18N, it is recommended to read through the official document, do your own configuration under the familiar.

Most of the time, we just need to use $t to meet our requirements. But as we get deeper and deeper into the language package, you’ll notice that the property path gets longer and longer, and in some components, you’ll need to write it many times, like index.header.title and index.header.subtitle, which are prefixed with index.header. We can write it twice here, but what if it’s 100 times? As a lazy programmer, how can you accept to do the same thing three times, let alone 100 times?

In fact, we can obtain the object set of the prefix and access it through the set object to save the repetitive writing of the prefix in the full length. In this case, we need to define the international set in computed in the SRC /views/index.vue component first:

export default {
  name: 'Index'.computed: {
    indexMsg() {
      return this.$t('index.header')}}};Copy the code

Next modify the writing method in the template:

<h1>{{ indexMsg.title }}</h1>
<h3>{{ indexMsg.subtitle }} </h3>
Copy the code

Note: This must be defined as a calculated property, otherwise view internationalization will not be updated automatically when switching languages.

News of diversity

Once when doing a login error message prompt, encountered a requirement: However, the interface only returns the number of remaining seconds. You need to calculate the remaining seconds based on the number of seconds. If the value is greater than 1 hour, the system prompts you to try again after xx minutes and XX seconds. The simplest way is to directly define two international keys, such as MSg1 and msg2, and then calculate the number of hours to do the if judgment.

However, as the project becomes larger and larger, and there are more and more similar requirements in the project, you will find that your language package has more and more key-value pairs. In the end, it takes a long time to get an attribute name. I don’t know if you have similar pain points with me, so I use $TC function to achieve such similar requirements.

$tc function allows us to an international key value can be split by pipeline operators | diverse information, as follows:

export default {
  // ...
  login: {
    tips: '{minute} {the second} second, please retry again after | {hour}, please retry again after hours',}};Copy the code

Then use it in the template:

<p>{{ $tc('login.tips', 1, {minute: 30, second: 29}) }}</p>
<p>{{ $tc('login.tips', 2, {hour: 1}) }}</p>
Copy the code

For the above requirement, I just need to calculate the value of hour based on the number of seconds returned by the interface, and then write a three-way operation to solve the problem:

hour >= 1 ? this.$tc('login.tips'.2, {hour: 1}) : this.$tc('login.tips'.1, {minute: 30.second: 29})
Copy the code

Optional array message

For optional internationalized message requirements, we can also implement arrays, such as an order state that needs to be internationalized, 0 to 5 for different states, we just need to define a simple array.

First define the language package:

export default {
  / /...
  order: {
    status: [
      'To be paid'.'To be shipped'.'Shipped'.'Signed for'.'Cancelled',].}};Copy the code

Then we just need to read the key based on the different states:

<span>{{ $t(`order.status[orderStatus]`) }}</span>

<script>
export default {
  name: 'Index',
  data() {
    return {
      orderStatus: 3}; },/ /...
};
</script>
Copy the code

Of course, here can also be achieved through a diversified way, you can try.

modular

As your project gets bigger and bigger, you’ll find that the SRC /lang/zh.js file gets bigger and bigger, and every time you change an international document, you’ll need to search through thousands of rows of objects to find the corresponding key-value pairs, and the unfazed hierarchy of attributes can be quite confusing.

SRC /lang/zh.js is a js file, so we can split it up into separate js files for maintenance. For example, we tried to split the zh.js file into SRC /lang/zh-modules/index.js, SRC /lang/zh-modules/login.js, SRC /lang/zh-modules/order.js:

// index.js
export default {
  index: {
    header: {
      title: 'the Vue - I18n sample'.subtitle: 'You will learn how to use vuE-i18n',}}};// login.js
export default {
  login: {
    tips: '{minute} {the second} second, please retry again after | {hour}, please retry again after hours',}};// order.js
export default {
  order: {
    status: [
      'To be paid'.'To be shipped'.'Shipped'.'Signed for'.'Cancelled',].}};Copy the code

Then introduce it once in the SRC /lang/zh.js file:

import index from './zh-modules/index';
import login from './zh-modules/login';
import order from './zh-modules/order';

export default{... index, ... login, ... order, };Copy the code

This makes it much clearer that the next time the product needs you to change the login-related copy, you just need to change the login.js module.

But if I split it by module, some people might wonder, what should I do? If I split it this way, the language module files will multiply with the language category.

Here is my solution, which is to merge the language files by modules. The so-called world trend, long united will be divided, divided will be unified. We can simply merge the same modules by file, such as the index module:

const zh = {
  index: {
    header: {
      title: 'the Vue - I18n sample'.subtitle: 'You will learn how to use vuE-i18n',}}};const en = {
  index: {
    header: {
      title: 'Vue-I18n Demo'.subtitle: 'You will learn how to use vue-i18n',,}}}export default {
  zh,
  en,
};
Copy the code

Then just add SRC /lang/index.js and change it a little:

import Vue from 'vue';
import VueI18n from 'vue-i18n';

import indexMsg from './modules/index';
import loginMsg from './modules/login';
import orderMsg from './modules/order';

Vue.use(VueI18n);

const messages = {
  zh: {... indexMsg.zh, ... loginMsg.zh, ... orderMsg.zh, },en: {... indexMsg.en, ... loginMsg.en, ... orderMsg.en, }, };const i18n = new VueI18n({
  locale: 'zh',
  messages,
});

export default i18n;
Copy the code

At this point you will notice that we no longer need the SRC /lang/en.js and SRC /lang/en.js files. And there is an advantage here is that after we ask the translator to help, we only need to modify and edit our same key value in the same file, is not convenient, hurry to try it ~

conclusion

This article is just a summary of my experience on internationalization solutions during the development process. I believe there are also many solutions to improve efficiency. Hopefully this post will solve some of the puzzles and pain points you have encountered in the development process, and you are welcome to comment or write to share your optimization solutions.

The source code in this

Project directory

You-May-Not-Know-Vuejs