简体   繁体   中英

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 ?

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, eg

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.

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>

You are using objects instead of arrays but JavaScript objects do not have a length property - you can try with arrays:

// English locale
{
  "message":
  {
    security_signing:
    {
      slides:
      [
        'Kitten1',
        'Kitten2'
      ]
    },
    signup:
    {
      slides:
      [
        'Kitten1',
        'Kitten2',
        'Kitten3'
      ]
    }
  }
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM