Vue.js vue在从后端加载i18n翻译后显示页面

Vue.js vue在从后端加载i18n翻译后显示页面,vue.js,fetch,vue-i18n,Vue.js,Fetch,Vue I18n,在我的应用程序中,翻译可以由管理员编辑,因此我需要从后端预加载它们,并在我拥有的vue应用程序中进行初始化。因此,我发现vue i18n包能够延迟加载消息()。但在他们的示例中,他们已经使用默认(en)消息初始化vue,但在我的示例中,我没有预加载默认消息。因此,我希望在创建VueI18n的新实例时从后端加载消息 以下是i18n.js文件: import Vue from 'vue' import VueI18n from 'vue-i18n' import {syncGetData} from

在我的应用程序中,翻译可以由管理员编辑,因此我需要从后端预加载它们,并在我拥有的vue应用程序中进行初始化。因此,我发现vue i18n包能够延迟加载消息()。但在他们的示例中,他们已经使用默认(en)消息初始化vue,但在我的示例中,我没有预加载默认消息。因此,我希望在创建VueI18n的新实例时从后端加载消息

以下是
i18n.js
文件:

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import {syncGetData} from "@/apiUtil";
import NProgress from 'nprogress'
import './sass/nprogress.scss'

Vue.use(VueI18n)


let loadedLanguages = []

export const i18n = new VueI18n({
  locale: navigator.language.split('-')[0] || process.env.VUE_APP_I18N_LOCALE,
  fallbackLocale: navigator.language.split('-')[0] || process.env.VUE_APP_I18N_LOCALE,
  messages: loadLanguage(navigator.language.split('-')[0] || process.env.VUE_APP_I18N_LOCALE)
})

function setI18nLanguage (lang) {
  i18n.locale = lang
  document.querySelector('html').setAttribute('lang', lang)
  return lang
}

export function loadLanguage(lang) {
  // If the language was already loaded
  if (loadedLanguages.includes(lang)) {
    return Promise.resolve(setI18nLanguage(lang))
  }
  NProgress.start();
  return syncGetData('/api/translations/' + lang)
    .then(function(data) {
      setI18nLanguage(lang)
      loadedLanguages.push(lang)
      return  data;
    })
    .catch(function (error) {
      console.error(error)
    }).finally(function () {
      NProgress.done();
    });
}

这里还有
main.js
(简化):

翻译的加载工作正常,但Vue在加载模板之前渲染模板,我看到的不是实际的翻译,而是翻译键。我尝试使用
v-clope
,但没有效果

因此,我想要实现的是,虽然翻译加载用户应该只看到加载栏(我使用的是
NProgress
,但您可以在
i18n.js
中看到用法),并且仅在加载翻译后渲染应用程序(可能不是渲染而是初始化)。取而代之的是:加载条和渲染应用程序都没有实际的翻译

提前谢谢

Michal Levýasnwer之后的更新

现在,
i18n.js
看起来像这样:

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import { syncGetData} from "@/apiUtil";
import NProgress from 'nprogress'
import './sass/nprogress.scss'

Vue.use(VueI18n)


let loadedLanguages = [];

export function initI18n() {
  const lang = navigator.language.split('-')[0] || process.env.VUE_APP_I18N_LOCALE

  return syncGetData('/api/translations/' + lang)
    .then(function(data) {
      console.log(data)
      setI18nLanguage(lang)
      loadedLanguages.push(lang)
      return new VueI18n({
        locale: lang,
        fallbackLocale: lang,
        messages: data
      })
    })
    .catch(function (error) {
      console.error(error)
    });
}

function setI18nLanguage (lang) {
  document.querySelector('html').setAttribute('lang', lang)
  return lang
}

export function loadLanguage(lang) {
  // If the language was already loaded
  if (loadedLanguages.includes(lang)) {
    return Promise.resolve(setI18nLanguage(lang))
  }
  NProgress.start();
  return syncGetData('/api/translations/' + lang)
    .then(function(data) {
      setI18nLanguage(lang)
      loadedLanguages.push(lang)
      return  data;
    })
    .catch(function (error) {
      console.error(error)
    }).finally(function () {
      NProgress.done();
    });
}

main.js
是:

import Vue from 'vue'
import App from './App.vue'
import {initI18n} from './i18n'
import NProgress from "nprogress";
import './sass/nprogress.scss'

NProgress.start();
initI18n().then(function(i18n) {
  new Vue({
    i18n,
    render: h => h(App)
  }).$mount('#app')
}).finally(function () {
  NProgress.done();
});
我可以确认,现在在我的
应用程序中的Vue初始化之前,b-z已加载消息。Vue
我有一个
控制台。在
挂载的
方法中有一个
日志

  mounted() {
    console.log(this.$i18n.messages)
  }
控制台日志的输出是
对象{main_title:“Calculation”,tab_you:“you”,tab_friend:“Your friend”,…}
,在它成为空对象之前


但是仍然
{$t('main_title')}
呈现
main_title
而不是
Calculation
替换
VueI18n
初始化如下:

import Vue from 'vue'
import VueI18n from 'vue-i18n'
import { syncGetData} from "@/apiUtil";
import NProgress from 'nprogress'
import './sass/nprogress.scss'

Vue.use(VueI18n)


let loadedLanguages = [];

export function initI18n() {
  const lang = navigator.language.split('-')[0] || process.env.VUE_APP_I18N_LOCALE

  return syncGetData('/api/translations/' + lang)
    .then(function(data) {
      console.log(data)
      setI18nLanguage(lang)
      loadedLanguages.push(lang)
      return new VueI18n({
        locale: lang,
        fallbackLocale: lang,
        messages: data
      })
    })
    .catch(function (error) {
      console.error(error)
    });
}

function setI18nLanguage (lang) {
  document.querySelector('html').setAttribute('lang', lang)
  return lang
}

export function loadLanguage(lang) {
  // If the language was already loaded
  if (loadedLanguages.includes(lang)) {
    return Promise.resolve(setI18nLanguage(lang))
  }
  NProgress.start();
  return syncGetData('/api/translations/' + lang)
    .then(function(data) {
      setI18nLanguage(lang)
      loadedLanguages.push(lang)
      return  data;
    })
    .catch(function (error) {
      console.error(error)
    }).finally(function () {
      NProgress.done();
    });
}

导出函数initI18n(){
const lang=navigator.language.split('-')[0]| | | process.env.VUE_APP_I18N_LOCALE
返回loadLanguage(lang).then(函数(数据){
返回新的VueI18n({
地点:朗,
后备地点:lang,
信息:数据
})
})
}
main.js

从“Vue”导入Vue
从“./App.vue”导入应用程序
从“/i18n”导入{initI18n}
initI18n().then(函数(i18n){
新Vue({
i18n,
渲染:h=>h(应用程序)
}).$mount(“#应用程序”)
})
Q更新后编辑: 看来你的本地化是错误的。VueI18能够同时使用多种语言,因此所有翻译密钥都应包含在“语言对象”中

而不是:

{
主要标题:“计算”,
你:“你”,
你的朋友:“你的朋友”,
...
}
您的API应该返回

{
“en”:{
主要标题:“计算”,
你:“你”,
你的朋友:“你的朋友”,
...
}
}
…其中“en”是语言标识符


检查您的浏览器控制台,我认为VueI18n应该警告丢失的键…

um,看起来您提到的方式应该是有效的,现在它正在初始化Vue之前加载翻译,但我仍然只看到翻译键,不确定为什么。。。我正在更新您的答案,并将使用新的信息/代码更新主要问题。我相信这是您从后端返回的翻译格式的问题。更新了我的答案…不,我现在返回这样的对象,但仍然
{{$t('main_title')}
不工作,但我可以像这样访问
{{$i18n.messages.en.main_title}
,如果我找不到任何解决方案,我可以使用它来问问题,获得解决方案,然后更改问题(在其中添加更多问题)不给予适当的信任是一种方式…(讽刺)好吧,你是对的,拿起你的答案:)谢谢!