vue-i18n doesn't update locale after integrating vuex

5.8k views Asked by At

I'm still new to Vue, but I feel like I'm almost getting the hang of it.. I managed to create an app that could translate to different languages where the content was loaded from LANG.json files.. the problem was that whenever I changed to a new view then it would turn back to the original translation..

So I tried to integrate Vuex to my application, but I can't seem to get it to work..

I believe this is all the relevant code:

src/i18n/index.js

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import store from './../store'

Vue.use(VueI18n)

export default new VueI18n({
  locale: store.state.Language,
  messages: {
    'en': require('./en.json'),
    'cn': require('./cn.json')
  }
})

src/store/index.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const actions = {
  changeLanguage: ({ commit }, data) => commit('changeLanguage', data)
}

const mutations = {
  changeLanguage (state, data) {
    this.state.Language = data
  }
}

const getters = {
  getLanguage: state => state.Language
}

const state = {
  Language: 'en'
}

export default new Vuex.Store({
  state,
  getters,
  actions,
  mutations
})

src/main.js

[...]
import store from './store'
import i18n from './i18n'
[...]
new Vue({
  el: '#app',
  router,
  store,
  i18n,
  render: h => h(App)
})

src/components/randomfile.js

<template>
[...]
<button v-on:click="en">English</button> 
<button v-on:click="cn">Chinese</button>
</template>
<script>
export default {
  name: 'navFooter',
  data () {
    return {
    }
  },
  methods: {
    en: function () {
      console.log('change lang')
      this.$store.dispatch('changeLanguage', 'en')
      // this.$i18n.locale = 'en'
    },
    cn: function () {
      this.$store.dispatch('changeLanguage', 'cn')
      // this.$i18n.locale = 'cn'
    }
  }
}
</script>

I'm guessing the problem is either related to this line: locale: store.state.Language, or because I'm doing something wrong with the dispatch, because in one of my views I write {{$store.state.Language}}, which renders to en on page load, but disappears after I click the buttons that call the methods for dispatching.

I call the translations with {{ $t('views.home.title') }} but I'm pretty sure that's still the way they should be called after integrating vuex (store), and the translations do appear as they should, they just don't update after clicking the buttons that dispatch changeLanguage.

Any help would be much appreciated


Edit: Actually, it seems the way I translated did make a difference.. after changing it to {{ $t('views.home.title', $store.state.Language) }} (maybe this should be this.$store.state.Language?)then the translations started working again.. but the translation state is still not persistent (meaning if I refresh the page or open a new URL, then it will change back to the English translations...

Any ideas why that is?

1

There are 1 answers

1
Shimotori On BEST ANSWER

Vuex store is not persisted. Reloading the page resets it.

To persist the locale, you should store it in a local storage (like IndexedDB) or a backend server.

Another way (not persisting) is to embed it in URL like /:locale/page. Then you can get the locale from the router params.

$t('views.home.title') uses the locale from this.$i18n.locale and you don't update this.$i18n.locale, then $t('views.home.title') shows the translation with the initial locale, 'en'.

$t('views.home.title', $store.state.Language) works because you specify the locale by yourself, not using this.$i18n.locale.