4

I'm using vue-i18n to handle localization in my app. I need to apply localization to the default value for a component prop:

export default {
  name: 'ExampleComponent',
  props: [{
    prompt: {
      required: false,
      type: String,
      default: $t('example.prompt.default')
   }]
}

$t is obviously not in scope as shown, but it seems that at the point the default value for the prop is being evaluated, this is not the component itself either, so this.$t is also undefined.

What's the best way to use VueI18n to translate the default value for a prop?

Ian Dickinson
  • 12,875
  • 11
  • 40
  • 67

2 Answers2

6

You can access $t in a callback function as the callback is evaluated in the context of the created component.

prompt: {
  required: false,
  type: String,
  default: function () {
    this.$t('example.prompt.default')
  }
}

The downside here is that the value will be undefined in the beforeCreate life-cycle hook. If you need it there, then your best bet is to instead set the default value to the key of your i18n definition (example.prompt.default), and use this.$t(this.prompt) instead.

Ohgodwhy
  • 49,779
  • 11
  • 80
  • 110
  • 3
    This doesn't work. I think you are missing a `return` statement in the default function. Also it is not responsive to a locale change. – Encrypted Apr 28 '21 at 12:34
  • It does work, or try es6 syntax: default: () => this.$t('error.couldNotGetData') – trainoasis May 04 '21 at 11:41
  • I am getting ```Property '$t' does not exist on type '{ type: StringConstructor; required: boolean; default: () => String; }'``` – Muhammad Tahir Qaiser Aug 28 '21 at 15:53
  • I don't think this can work because `this` isn't available in the `default` function, as per [the docs](https://v2.vuejs.org/v2/guide/components-props.html?redirect=true#:~:text=Note%20that%20props%20are%20validated%20before%20a%20component%20instance%20is%20created%2C%20so%20instance%20properties%20(e.g.%20data%2C%20computed%2C%20etc)%20will%20not%20be%20available%20inside%20default%20or%20validator%20functions.). – Allan Lewis Feb 22 '22 at 14:40
0

You can import the VueI18n instance from where you imported it.

import i18n from '../i18n'

export default {
  name: 'ExampleComponent',
  props: [{
    prompt: {
      required: false,
      type: String,
      default: i18n.t('example.prompt.default')
   }]
}

i18ns.js

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

Vue.use(VueI18n)

function loadLocaleMessages () {
  const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
  const messages = {}
  locales.keys().forEach(key => {
    const matched = key.match(/([A-Za-z0-9-_]+)\./i)
    if (matched && matched.length > 1) {
      const locale = matched[1]
      messages[locale] = locales(key)
    }
  })
  return messages
}

export default new VueI18n({
  locale: process.env.VUE_APP_I18N_LOCALE || 'en',
  fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
  messages: loadLocaleMessages()
})

Pierre Said
  • 3,660
  • 1
  • 16
  • 28