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


    一、使用vue-i18n

    1、安装

    npm install vue-i18n --save
    
    • 1

    俺的版本:
    “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
    
    • 1

    2、使用

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

    新建zh.json:

    {
     "navbar": {
       "welcome": "欢迎"
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

     
    新建en.json:

    {
     "navbar": {
       "welcome": "welcome"
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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}`
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    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
        }
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5、在nuxt.config.js中引入

    export default {
      router: {
         middleware: 'i18n'
      },
    
      plugins: [
        '~/plugins/i18n',
      ],
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    6、在页面使用

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

    7、切换语言

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

     <b-form-select v-model="selected" :options="lang" @change="isSelected"></b-form-select>
    
    • 1
     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'
           }
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3、踩坑

    但是出现了诸多问题:

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

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

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

     

    二、使用nuxt-i18n

    1、安装

    npm install nuxt-i18n
    
    • 1

    2、使用

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

    // zh.js
    
    export default{
     "navbar": {
       "welcome": "欢迎"
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    // en.js
    
    export default{
     "navbar": {
       "welcome": "welcome"
     }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    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 }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    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 // 可以外部引入,也可以在此文件中配置
          }]
      ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    3、踩坑

    三、浏览器语言检测

    1、使用

    在nuxt.config.js中的modules配置

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

    完整代码:

      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
              }
          }]
      ],
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    2、踩坑

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

    浏览器语言代码:https://wenku.baidu.com/view/5c76cee05cbfc77da26925c52cc58bd6318693ee.html

    四、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
         ]
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    单个页面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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    五、切换语言

    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
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

    2、踩坑

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

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

    所以改为监听locale的变化

    watch: {
        // 监听语言切换
        locale(val) {
          this.$i18n.setLocale(val)
          this.$i18n.setLocaleCookie(val)
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

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

  • 相关阅读:
    【Python入门】Python的List容器二
    Cloudera发布全球企业数据成熟度报告,混合云趋势中有效数据战略是关键
    程序员必备,一款让你提高工作效率N倍的神器uTools
    SHC加密sh脚本
    Python实战:Python常用IDE选择
    车牌比对程序源代码(c++)
    零零信安-D&D数据泄露报警日报【第41期】
    Vue3中的常用组件通信大总结 包括最Vue3.4defineModel()实现组件双向绑定
    【CSS】设置文字(文本)的渐变色
    【计算机网络基础实验】实验二 有线IP互通网络实践
  • 原文地址:https://blog.csdn.net/weixin_45693257/article/details/125378250