微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从后端加载i18n翻译后的vue显示页面

如何解决从后端加载i18n翻译后的vue显示页面

在我的应用程序中,翻译可以由admin编辑,因此我需要从后端预加载它们并在我拥有的vue应用程序中进行初始化。因此,我发现vue i18n软件包具有延迟加载消息(link)的能力。但是在他们的示例中,他们已经使用认(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(简体):

import Vue from 'vue'
import App from './App.vue'
import {i18n} from './i18n'
new Vue({
  i18n,render: h => h(App)
}).$mount('#app')

正在加载翻译,但是Vue在加载模板之前先渲染模板,我看到的是翻译键,而不是实际的翻译。我尝试使用v-cloak,但没有帮助。

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

谢谢!

在MichalLevý解决之后更新

现在,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();
});

我可以确认现在在App.vue的Vue开头b-z之前已加载消息,我在console.log方法中有一个mounted

  mounted() {
    console.log(this.$i18n.messages)
  }

并且控制台日志的输出Object { main_title: "Calculation",tab_you: "You",tab_friend: "Your Friend",...},然后才是空对象。

但是<h2 class="title-form">{{ $t('main_title') }}</h2>仍呈现main_title而不是Calculation

解决方法

用以下内容代替VueI18n的初始化:

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

main.js

import Vue from 'vue'
import App from './App.vue'
import { initI18n } from './i18n'

initI18n().then(function(i18n) {
  new Vue({
    i18n,render: h => h(App)
  }).$mount('#app')
})

Q更新后进行编辑:

看来您的本地化format是错误的。 VueI18能够一次使用多种语言,因此所有翻译键都应包含在“语言对象”中

代替:

{ 
  main_title: "Calculation",tab_you: "You",tab_friend: "Your Friend",...
}

您的API应该返回

{ 
  "en": {
    main_title: "Calculation",...
  }
}

......,其中“ en”是语言标识符

检查您的浏览器控制台,我相信VueI18n应该警告您缺少密钥...

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。