当前位置: 首页 > 工具软件 > i18n-locales > 使用案例 >

nuxt.js + vue-i18n + nuxt-i18n 实现多语言国际化

养焱
2023-12-01

一、使用vue-i18n

1、安装

npm install vue-i18n --save

俺的版本:
“nuxt”: “^2.15.8”
“vue-i18n”: “^8.27.0”
 
注意: 如果nuxt版本是2的话,直接安装vue-i18n会是最新版本的,最新版本的vue-i18n是基于vue3的,会显示报错,所以低版本的nuxt,需要安装指定版本(低于9)

npm install vue-i18n@8.27.0 --save

2、使用

1、新建lang文件夹,分别新建对应语言的json文件
举个例子~

新建zh.json:

{
 "navbar": {
   "welcome": "欢迎"
 }
}

 
新建en.json:

{
 "navbar": {
   "welcome": "welcome"
 }
}

2、新建文件夹plugins(放置插件),新建i18n.js

import Vue from 'vue'
import VueI18n from 'vue-i18n'

Vue.use(VueI18n)

export default ({ app, store }) => {
  app.i18n = new VueI18n({
    locale: store.state.locale,
    fallbackLocale: 'zh',
    messages: {
      'zh': require('~/lang/zh.json'),
      'en': require('~/lang/en.json')
    }
  })
  app.i18n.path = (link) => {
    if (app.i18n.locale === app.i18n.fallbackLocale) {
      return `/${link}`
    }
    return `/${app.i18n.locale}/${link}`
  }
}

3、新建文件夹middleware(中间件),新建i18n.js

export default function ({ isHMR, app, store, route, params, error, redirect }) {

  if (isHMR) {
    return
  }
  
  else if (!params.lang) {
    return redirect('/zh' + route.fullPath)
  }

  const locale = params.lang || 'zh'

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

}

4、在store文件夹里,新建index.js

export const state = () => ({
  locales: ['zh', 'en'],
  locale: 'zh'
})

export const mutations = {
  SET_LANG(state, locale) {
    if (state.locales.indexOf(locale) !== -1) {
      state.locale = locale
    }
  }
}

5、在nuxt.config.js中引入

export default {
  router: {
     middleware: 'i18n'
  },

  plugins: [
    '~/plugins/i18n',
  ],
 }

6、在页面使用

<h1>{{$t('navbar.welcome')}}</h1>

7、切换语言

我这里用得是bootstrapVue的组件,根据自己的页面情况而定

 <b-form-select v-model="selected" :options="lang" @change="isSelected"></b-form-select>
 computed: {
    lang() {
      return [
        {text: 'CN', value: 1},
        {text: 'EN', value: 2}
      ]
    }
  },
 methods:{
 // 切换语言
   isSelected(val) {
       this.selected = val
        if (val === 1) {
         this.$i18n.locale = 'zh'
       } else if (val === 2) {
         this.$i18n.locale = 'en'
       }
 }

3、踩坑

但是出现了诸多问题:

一、
vuex没有数据持久化,因为nuxt是服务器渲染,在created生命周期里,如window、Document、localStorage等对象只存在于客户端,都用不了

二 、
中间件的路由重定向不会随着页面刷新而刷新路由,必须发生路由跳转才能刷新

结论:vuex数据持久化使用cookie插件实现了,但是不知道如何刷新中间件,百度后也无果,所以决定使用nuxt.js的nuxt-i18n

 

二、使用nuxt-i18n

1、安装

npm install nuxt-i18n

2、使用

1、新建lang文件夹,分别新建对应语言的js文件

// zh.js

export default{
 "navbar": {
   "welcome": "欢迎"
 }
}
// en.js

export default{
 "navbar": {
   "welcome": "welcome"
 }
}

2、新建文件夹plugins,新建i18n.js

import zh from '../lang/zh'
import en from '../lang/en'
import ja from '../lang/jp'
import ko from '../lang/kr'

export default {
  locale: 'zh',
  fallbackLocale: 'zh',
  messages: { zh, en, ja, ko }
}

3、在nuxt.config.js中配置

import i18n from "./plugins/i18n"

modules: [
    [
      'nuxt-i18n', {
      defaultLocale: 'zh',
      // 根据项目情况,酌情配置
      locales: [
            {
              code: 'zh',
              iso: 'zh-CN',
              text: 'CN',
            },
            {
              code: 'en',
              iso: 'en-US',
              text: 'US',
            },
            {
              code: 'ja',
              iso: 'ja-JP',
              text: 'JP',
            },
            {
              code: 'ko',
              iso: 'ko-KR',
              text: 'KR'
            },
          ],
          vueI18n: i18n // 可以外部引入,也可以在此文件中配置
      }]
  ],

3、踩坑

三、浏览器语言检测

1、使用

在nuxt.config.js中的modules配置

 // 浏览器语言检测
 detectBrowserLanguage: {
    useCookie: true // 缓存浏览器语言,如果需要每次打开浏览器都重新获取,就为false
    // onlyOnRoot: true
 }

完整代码:

  modules: [
    [
      'nuxt-i18n', {
      defaultLocale: 'zh',
      locales: [
            {
              code: 'zh',
              iso: 'zh-CN',
              text: 'CN',
            },
            {
              code: 'en',
              iso: 'en-US',
              text: 'US',
            },
            {
              code: 'ja',
              iso: 'ja-JP',
              text: 'JP',
            },
            {
              code: 'ko',
              iso: 'ko-KR',
              text: 'KR'
            },
          ],
          vueI18n: i18n,
          // 浏览器语言检测
          detectBrowserLanguage: {
            useCookie: true
            // onlyOnRoot: true
          }
      }]
  ],

2、踩坑

因为日语,韩语的语言代码写错了,导致一直检测不到大家一定要注意不要犯俺这种低级错误,如果不确定可以看下方的文档:

浏览器语言代码:https://blog.csdn.net/Noah_ZX/article/details/125552960

四、SEO国际化

1、使用

所有页面统一seo:

// nuxt.config.js:

export default {
  head () {
    const i18nHead = this.$nuxtI18nHead({ addSeoAttributes: true })
    return {
      htmlAttrs: {
        myAttribute: 'My Value',
        ...i18nHead.htmlAttrs
      },
      meta: [
        {
          hid: 'description',
          name: 'description',
          content: 'My Custom Description'
        },
        ...i18nHead.meta
      ],
      link: [
        {
          hid: 'apple-touch-icon',
          rel: 'apple-touch-icon',
          sizes: '180x180',
          href: '/apple-touch-icon.png'
        },
        ...i18nHead.link
     ]
    }
  }
}

单个页面seo:

export default{
 data() {
    return {}
 },
 head() {
    return {
      title: `${this.$t('navbar.name')} - ${this.$t('index.title')} - ${this.$t('footer.corporate_name')}`,
      meta: [
        { hid: 'description', name: 'description', content: this.$t('seo.description') },
        { hid: 'keywords', name: 'keywords', content: this.$t('seo.keywords') },
      ]
    }
  }
}

五、切换语言

1、使用

因为需要切换多种语言,所以使用select进行切换

<b-form-select v-model="locale">    
 <b-form-select-option v-for="(item, index) in availableLocales" :key="index" :value="item.code" @click.prevent.stop="$i18n.setLocale(item.code)">{{item.text}}</b-form-select-option>-->       
</b-form-select>

export default{
 data() {
  return {
     locale: this.$i18n.locale, // 语言
  }
 },
 computed: {
    availableLocales() {
      return this.$i18n.locales
    }
  }
}

效果: 切换语言后,导航栏的路由也会切换到对应语言

2、踩坑

在火狐浏览器能够正常切换,但是在谷歌浏览器里无法实现,搜索后发现

谷歌浏览器不支持用click点击事件操作select标签!!!

所以改为监听locale的变化

watch: {
    // 监听语言切换
    locale(val) {
      this.$i18n.setLocale(val)
      this.$i18n.setLocaleCookie(val)
    }
  }

目前的学习就到这里啦~,如果还有其他问题可以请多多交流

 类似资料: