Nuxt.js i18n本地化在SPA模式下不起作用

时间:2019-08-18 05:28:48

标签: javascript single-page-application nuxt.js vue-i18n

我以通用模式开发了项目Nuxt.js,并使用i18n进行了本地化,但现在我想更改为spa模式,但i18n不会更改语言。 这是代码。 文件:nuxt.config.js

import colors from "vuetify/es5/util/colors";

export default {
  mode: "spa",
  /*
   ** Headers of the page
   */
  head: {
    meta: [
      { charset: "utf-8" },
      { name: "viewport", content: "width=device-width, initial-scale=1" },
      {
        hid: "description",
        name: "description",
        content: process.env.npm_package_description || ""
      }
    ],
    link: [
      { rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
      {
        rel: "stylesheet",
        href:
          "https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons"
      }
    ]
  },
  /*
   ** Customize the progress-bar color
   */
  loading: { color: "#fff" },
  /*
   ** Global CSS
   */
  css: ["~/assets/main.css"],

  router: {
    middleware: "i18n"
  },
  /*
   ** Plugins to load before mounting the App
   */
  plugins: [
    "~/plugins/mdi-font.js",
    "~/plugins/i18n.js",
    "~/plugins/axios.js",
    { src: "~/plugins/flag.js", ssr: false }
  ],
  /*
   ** Nuxt.js modules
   */
  modules: [
    "@nuxtjs/vuetify",
    // Doc: https://axios.nuxtjs.org/usage
    "@nuxtjs/axios"
  ],
  /*
   ** Axios module configuration
   ** See https://axios.nuxtjs.org/options
   */
  axios: {},
  /*
   ** vuetify module configuration
   ** https://github.com/nuxt-community/vuetify-module
   */
  vuetify: {
    theme: {
      primary: colors.blue.darken2,
      accent: colors.grey.darken3,
      secondary: colors.amber.darken3,
      info: colors.teal.lighten1,
      warning: colors.amber.base,
      error: colors.deepOrange.accent4,
      success: colors.green.accent3
    }
  },
  /*
   ** Build configuration
   */
  build: {
    /*
     ** You can extend webpack config here
     */
    extend(config, ctx) {}
  }
};

文件:middleware/i18n.js

export default function ({ isHMR, app, store, route, params, req, error, redirect }) {
    if (isHMR) { // ignore if called from hot module replacement
        return;
    }

    if (req) {
        if (route.name) {
            let locale = null;

            // check if the locale cookie is set
            if (req.headers.cookie) {
                const cookies = req.headers.cookie.split('; ').map(stringCookie => stringCookie.split('='));
                const cookie = cookies.find(cookie => cookie[0] === 'locale');

                if (cookie) {
                    locale = cookie[1];
                }
            }

            // if the locale cookie is not set, fallback to accept-language header
            if (!locale) {
                locale = req.headers['accept-language'].split(',')[0].toLocaleLowerCase().substring(0, 2);
            }

            store.commit('SET_LANG', locale);
            app.i18n.locale = store.state.locale;
        }
    }
};

store/index.js

export const state = () => ({
    locales: [
        {
            code: 'en',
            name: 'EN',
            flag: 'us'
        },
        {
            code: 'fa',
            name: 'FA',
            flag: 'af'
        },
        {
            code: 'pa',
            name: 'PA',
            flag: 'af'
        }
    ],
    locale: 'en'
});

export const mutations = {
    SET_LANG(state, locale) {
        if (state.locales.find(el => el.code === locale)) {
            state.locale = locale
        }
    }
};

和licalize文件位于locales/fa.json and en.json

3 个答案:

答案 0 :(得分:0)

  

导出默认功能({isHMR,应用,商店,路线,参数,要求,   错误,重定向})

因此在SAP模式下不会接收到粗体参数 req 。有关更多信息,您可以访问此link

因此,您必须尝试使用​​另一个参数的另一种方式,例如,您可以看到以下代码:

export default function ({
  isHMR, app, store, route, params, error, redirect
}) {
    const defaultLocale = app.i18n.fallbackLocale
  // If middleware is called from hot module replacement, ignore it
  if (isHMR) return
  // Get locale from params

                const locale = params.lang || defaultLocale
                if (store.state.locales.indexOf(locale) === -1) {
                  return error({
                    message: 'This page could not be found.',
                    statusCode: 404
                  })
                }

  // Set locale
  store.commit('SET_LANG', locale)
  app.i18n.locale = store.state.locale
  // If route is /<defaultLocale>/... -> redirect to /...

              if (locale === defaultLocale && route.fullPath.indexOf('/' + defaultLocale) ===
                0) {
                const toReplace = '^/' + defaultLocale
                const re = new RegExp(toReplace)
                return redirect(
                  route.fullPath.replace(re, '/')
                )
        } 
}

答案 1 :(得分:0)

对于SPA,您可以使用js-cookie, 因此null中的代码将更改为

middleware/i18n.js

希望有帮助。

答案 2 :(得分:0)

就我而言,我在 Fr 中有自定义路由(在 nuxt.config.js 中设置为额外的自定义路由),但它也不起作用。

我最终自己检测了语言环境,并更新了其余代码的内部 i18n 语言环境(问题 #1067):

async asyncData({$axios, $payloadURL, route, app, store}) {
  const [isFr] = route.fullPath.match(/^\/?fr_CA\/?/i) || []
  const locale = isFr ? 'fr_CA' : 'en'
  // NuxtI18n does not recognize the FR version of custom routes. :(
  // https://github.com/nuxt-community/i18n-module/issues/1067
  app.i18n.locale = locale
  ...
}