Vue-i18n - проблема с динамической локализацией из http-запроса - PullRequest
0 голосов
/ 10 июня 2018

Я пытаюсь загрузить локализацию из HTTP-вызова, так как я хочу, чтобы языки были динамичными и управляемыми, а не доставлял их вместе с приложением.

Я обошел вокруг пример SSR и некоторые измоя собственная реализация.Но при первоначальном рендере язык не загружается.При изменении маршрута на стороне клиента все обновляется.

i18n.js

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import en from './en.json'
import ar from './ar.json'
import axios from 'axios'

Vue.use(VueI18n)

const fallbackLocale = 'en'
let defaultLocale = 'ar'

export const i18n = new VueI18n({
  locale: defaultLocale, // set locale
  fallbackLocale: fallbackLocale,
  messages: {
    'en': en
  }
})

export function createI18n () {
  return i18n
}

Маршрутизатор - router.beforeEach

router.beforeEach((to, from, next) => {
    if (router.app.$store) {
        router.app.$store
          .dispatch('getI18nData')
          .then(function(){
            router.app.$i18n.setLocaleMessage('ar',router.app.$store.getters.getLocale)
            return next()
          })
          .catch(() => console.log('getI18nData-error'))
      } else {
        next()
      }
  })

Действие хранилища - для извлечения локали

getI18nData ({ commit }) {
   try {
     axios.get('http://localhost:8080/lang?lang=ar')
    .then(function (response) {
      let locale = response.data
      commit('setLocale', { locale })
    })
    .catch(function (error) {
      console.log('Error:getI18nData')
    })
   } catch (error) {
     console.error(error);
   }
 }

Выводы: i18n инициализируется до router.beforeEach, где он должен инициализироваться после router.beforeEach.

Github Issue Link

1 Ответ

0 голосов
/ 10 июня 2018

Хорошо, если быть более подробным: вы не хотите смешивать try / catch с цепочкой обещаний, но вам нужно вернуть обещание с getI18nData, иначе отправка не будет ждать.Итак, вы либо:

getI18nData ({ commit }) {
    // axios.get() returns a promise already, so we can just return the whole thing:
    return axios
      .get('http://localhost:8080/lang?lang=ar')
      .then(function (response) {
        let locale = response.data
        commit('setLocale', { locale })
      })
      .catch(function (error) {
        console.log('Error:getI18nData')
      });
}

Или вы используете async / await (который позволяет try / catch):

async getI18nData ({ commit }) {
  try {
    let response = await axios.get('http://localhost:8080/lang?lang=ar');
    let locale = response.data
    commit('setLocale', { locale })
  } catch (error) {
    console.error(error);
  }
}

Я хотел бы добавить, что мне нравится async /Опция await лучше, но в vuex-land это обычно приводит к необходимости выполнять все асинхронно / await (если вы используете вложенные вызовы диспетчеризации).Поэтому, в зависимости от остальной части вашей кодовой базы, может быть проще просто вернуть обещание.

...