Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access vue-i18n messages as object

I want to create a dynamical slider which depends on the page.

    security_signin: {
        slide1: 'Kitten1',
        slide2: 'Kitten2',
    },
    signup: {
        slide1: 'Kitten1',
        slide2: 'Kitten2',
        slide3: 'Kitten3'
    }

The thing is I want to render in my component my slider in function of the number of slide.

So this is something like this:

<slide v-for="(item, index) in $t('message.'+page).length">
    <p v-html="$t('message.'+page+'.slide'+index)"></p>
</slide>

However I do not manage to access properly messages this way. Since $t('message.'+page).length is giving me back the length of the first slide (7 in the Kitten1 case).

Is there a way to access i18n without recreating an instance of it ?

like image 741
Baldráni Avatar asked Dec 17 '22 21:12

Baldráni


2 Answers

It's very simple, access the messages property from $i18n. For instance:

<slide v-for="(item, index) in Object.keys($i18n.messages[$i18n.fallbackLocale].message[page]).length">
    <p v-html="$t('message.'+page+'.slide'+index)"></p>
</slide>

In more detail, $i18n.messages holds all your translations, e.g.

en: {
    security_signin: {
        slide1: 'Kitten1',
        slide2: 'Kitten2',
    },
    signup: {
        slide1: 'Kitten1',
        slide2: 'Kitten2',
        slide3: 'Kitten3'
    }
}

Subset a locale of your choice, $i18n.fallbackLocale for the fallback locale or $i18n.locale for your current locale. You should obtain your javascript object.

Be very careful, when you translate with $t() any missing translations are recovered from the fallback locale. But when you access the javascript object directly, you give up this safety net. Some locales may have missing keys.

In this case fallbackLocale suffices because we don't want to access the translations, only the number of elements.

like image 111
Javier Avatar answered Dec 30 '22 10:12

Javier


Okay so it appears that $t() is always returning a string.

So the solution I found out was to import messages in my components and directly use it from there :

import messages from '../messages'

export default {
   props: ['page', 'locale'],
   data(){
       return {
           slides: messages[this.locale].message[this.page]
       }
   }
}

<slide v-for="(slide, i) in slides">
    <p v-html="slide"></p>
    <img :src="'/assets/img/slider-bg-'+ i +'.png'" alt="">
</slide>
like image 35
Baldráni Avatar answered Dec 30 '22 11:12

Baldráni