Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use vue-i18n with Vue class components?

The following code:

import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class SomeComponent extends Vue {
  public someText = this.$t('some.key')
}

Throws an error:

[Vue warn]: Error in data(): "TypeError: i18n is undefined"

I made sure to initialize Vue with Vue.use(VueI18n) and new Vue({ /* ... */, i18n }). The i18n object is initialized this way:

new VueI18n({
  locale: DEFAULT_LOCALE, // imported
  fallbackLocale: 'en',
  messages // imported
})

Translations work perfectly fine as long as they are not immediately called, for example in templates or in component methods.

This vue-i18n issue seems to imply that there is an initialization problem.
I could work around this by using methods and only translating in templates, but there is a specific instance out of my control in which such immediate calls happen: Vuetify input rules.

someRule = [(v) => !!v || this.$t('field.must_not_be_empty')]

These rules are executed immediately, even with lazy-validation on Vuetify forms.

I have identified two possible solutions:

  1. Circumventing the Vuetify rules system and allowing to simply return a string to be translated within the template itself;
  2. Solving the $t immediate availability issue.

Sadly I have not been able to accomplish any of these.

Is there any way to solve this problem?

like image 970
Kyll Avatar asked Jan 09 '19 20:01

Kyll


1 Answers

The issue lied in the use of this.
Basically, Vue needs a very specific execution context that is not the same as what is normally accessible in the root context of a fresh class.

The solution ends up being very simple: Use a getter.

import Vue from 'vue'
import Component from 'vue-class-component'

@Component
export default class SomeComponent extends Vue {
  public get someText () { return this.$t('some.key') }
}
like image 118
Kyll Avatar answered Nov 14 '22 18:11

Kyll