kazupon/vue-i18n

Formatting is broken when switching language

Open

#983 创建于 2020年8月28日

在 GitHub 查看
 (11 评论) (1 反应) (0 负责人)JavaScript (7,181 star) (886 fork)batch import
Status: In Progresshelp wanted

描述

vue & vue-i18n version

Vue version: 2.6.11 Vue-i18n version: 8.18.2

Reproduction Link

https://codesandbox.io/s/elastic-shockley-wjw0z

Steps to reproduce

When using a formatter like the one provided by the official documentation, and switching locale, the formatter is not aware of this change.

(INFO: I tried this version of the formatter but it seems broken : TypeError: fn(...).map is not a function)

So I added this method to the formatter:

// Formatter.js
changeLocale(locale) {
  this._locale = locale;
  this._formatter = new MessageFormat(locale);
}

Then I can use this method when switching locale:

// App.vue
switchLocale(locale) {
  this.$i18n.locale = locale;
  this.$i18n.formatter.changeLocale(locale);
},

I don't know if it's the proper way to do this, but it solves partially my problem. Maybe there is another way to achieve this?

BUT, there's still a bug, formatted messages doesn't update when the translation string is exactly the same in both languages! Example:

const translations = {
  fr: {
    test: {
      number: {
        first: "Mon nombre est {myNumber, number, integer}",
        second: "{myNumber, number, integer}" // exact same string in 'en' and 'fr'
      },
      date: {
        first: "Ma date est {myDate, date, medium}",
        second: "{myDate, date, medium}" // exact same string in 'en' and 'fr'
      }
    }
  },
  en: {
    test: {
      number: {
        first: "My number is {myNumber, number, integer}",
        second: "{myNumber, number, integer}" // exact same string in 'en' and 'fr'
      },
      date: {
        first: "My date is {myDate, date, medium}",
        second: "{myDate, date, medium}" // exact same string in 'en' and 'fr'
      }
    }
  }
};

What is Expected?

When I use translation strings in a template and I switch locale, I expect the strings to be formatted in the chosen locale.

Number first

  • template: {{ $t('test.number.first', { myNumber: 2440 }) }}
  • expected output:
    • en: My number is 2,440 ✔️
    • fr: Mon nombre est 2 440 ✔️

Number second

  • template: {{ $t('test.number.second', { myNumber: 2440 }) }}
  • expected output:
    • en: 2,440 ✔️
    • fr: 2 440

Date first

  • template: {{ $t('test.date.first', { myDate: '2020-08-28 13:47:38+02:00' }) }}
  • expected output:
    • en: My date is Aug 28, 2020 ✔️
    • fr: Ma date est 28 août 2020 ✔️

Date second

  • template: {{ $t('test.date.second', { myDate: '2020-08-28 13:47:38+02:00' }) }}
  • expected output:
    • en: Aug 28, 2020 ✔️
    • fr: 28 août 2020

What is actually happening?

Number second

  • actual output:
    • fr: 2,440

Date second

  • actual output:
    • fr: Aug 28, 2020

As I said before, the concerned translation strings are those that are exactly the same in 'en' and 'fr', so I guess it could be a cache issue?

Any idea how to solve this?

贡献者指南