NuxtJS使用vue-i18n实现国际化多语言切换,快速上手

本文阅读 7 分钟
广告

写在文章开头:现在csdn真的是越来越垃圾了,我就没见过这么垃圾的网站,教程就TM写一半,最关键的东西不写,东西说得含含糊糊的,还尼玛好意思收费。呀屎拉你!
这篇文章是我在Nuxt学习过程中的整理,最近用这玩意做完了一个联系项目,也算是积累了不少的东西,其中多语言切换因为csdn教程带偏的缘故花费了额外的时间,虽然不复杂,其实也没有记录的必要,但是我就是想全部发出来,让那些垃圾还收费的教程没人看。
1_GzDBs0lKGg35RRK50dTNtQ.jpeg

第一步:安装vue-i18n插件:

1.我的项目是vue+NuxtJS,所以是使用vue的插件,使用终端进入项目目录后,执行如下指令,安装vue-i18n:

npm install --save vue-i18n

2.这里可能会遇到第一个问题,因为我还没使用vue3.0,所以会提示组件兼容错误,这时可以安装vue-i18n的旧版本,通过如下指令查询vue-i18n全部版本

npm view vue-i18n versions

选择一个旧版安装

npm install --save vue-i18n@版本号

3.创建locales文件夹,因为上一步是zh语言,所以在这个文件夹内创建zh.json,如果是其它的语言,比如英文,就可以再创建en.json,内容本质上就是json数据。

{
    "home": {
      "title": "欢迎来到首页",
      "meta": "这是一个简单的网站"
    }
}

4.创建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('~/locales/zh.json'),
      'en': require('~/locales/en.json')
    }
  });
  app.i18n.path = (link) => {
    if (app.i18n.locale === app.i18n.fallbackLocale) {
      return `/${link}`;
    }
    return `/${app.i18n.locale}/${link}`;
  }
}

这个文件夹主要负责引入创建的语言库json文件,并且定义页面路径的跳转。

5.创建store文件夹(有就不用了),在index.js(没有就创建)文件中加入如下代码:

export const state = ()=> ({
    locales: ['en', 'zh'],
    locale: 'zh'
})
export const mutations = {
  SET_LANG(state, locale) {
        if (state.locales.indexOf(locale) !== -1) {
            state.locale = locale
        }
    }
}

6.随后,项目根目录创建middleware文件夹,在文件夹内创建i18n.js,内容如下:

export default function ({
  isHMR, app, store, route, params, error, redirect
}) {
  const oldLocale = store.state.locale;
  if (isHMR) {
    return;
  }
  else if (!params.lang) {
    if(route.matched.length){
      return redirect('/'+oldLocale+'/'+route.fullPath);
    }else{
      return redirect('/'+oldLocale+'/');
    }

  }else if (params.lang){
    if (store.state.locales.indexOf(params.lang) === -1) {
      return redirect('/'+oldLocale+'/'+route.fullPath);
    }
  }
  const locale = params.lang || oldLocale;
  store.commit('SET_LANG', locale); // set store
  app.i18n.locale = store.state.locale;
}

这里的逻辑是首先对路由进行判断,对404页面自动回到首页(并切换为store中默认配置的语言),对已存在的页面自动加上语言路径。(网上很多的教程这个文件的配置都有问题,会导致404页面无限跳转,是真的坑)

7.在nuxt.config.js的bulid中,新增如下代码:

vendor: ['vue-i18n']

在plugins中,新建如下代码:

'@/plugins/i18n.js'

同时在nuxt.config.js中新增如下代码:

  router: {
    middleware: 'i18n'
  },
  generate: {
    routes: ['/', '/zh']

  },

1.png
其中generate的routes部分只需要将对应语言的首页写入其中,而根目录“/”是必须的,不然会导致项目部署时无法访问。到此,基础配置完成。

第二步:页面调用语言和切换。

1.在页面中,可以直接调用json文件中的字段(所以不同的json文件需要有相同的字段,才可以保证语言切换效果)

{{ $t('home.title') }}

如果需要调用当前的语言类型,可以通过如下代码:

this.$i18n.locale

设置语言就可以直接给上述的字段赋(不过赋值不是实时生效),如:

this.$i18n.locale = "en"

2.实际的代码案例如下(都是vue代码),首先是html部分:

<a href="javascript:;" @click="setLang('zh')">简体中文</a>
<a href="javascript:;" @click="setLang('en')">English</a>

js部分,实际上就是setLang方法:

setLang(lang){
  var that = this;
  that.$i18n.locale =lang;
  that.$router.push({path:'/'+lang});
},

到这里,实际上已经结束了,无论是使用还是SEO效果都没有啥问题。
但是,实际上还可以更进一步的优化。比如,当访问404页面时自动跳转到当前用户设置的语言,而不是默认的语言。比如,前台可以随时调用当前用户设置的语言进行其它的判断,而不会因为页面的刷新而失效为默认语言。所以,如果还需要继续优化或者满足更多需求的话,请看下一步。

第三步:持久存储语言设置,优化访问效果

nuxt的特性是ssr,这里的配置将模式变为了spa模式,失去了服务端渲染的意义,所以实际上完成第二步即可。或者使用服务端cookies插件代替持久化插件。

1.需要安装vuex-persistedstate插件,原理是将vuex的数据放进浏览器的sessionStorage或localStorage

npm install --save vuex-persistedstate

如果安装报兼容错误,可以通过如下代码查找版本列表:

npm view vuex-persistedstate versions

然后安装旧版

npm install --save vuex-persistedstate@版本号

2.在NuxtJs项目的plugins目录下(如果没有就创建),新建vue-persistedstate.js,内容如下:

import createPersistedState from 'vuex-persistedstate'

export default ({ store }) => {
  createPersistedState({
    storage: sessionStorage
  })(store)
}

3.在第二步的store中index.js的开头加入如下代码:

import createPersistedState from "vuex-persistedstate"
export const plugins = [createPersistedState()];

4.在nuxt.config.js中修改mode字段为spa(如果没有就添加)

mode:'spa',

5.上一步完成后,如果访问404页面,就会调用当前设置语言而不是默认语言,同时可以通过以下代码随时调用当前语言:

//从i18n调用
that.$i18n.locale
//从store中调用
that.$store.state.locale

6.设置语言的方法就可以改为如下:

setLang(lang){
  var that = this;
  that.$i18n.locale =lang;
  that.$store.commit('SET_LANG', lang);
  that.$router.push({path:'/'+lang});
},

一些补充

我的项目最终放弃了全站静态方案,因为多语言切换下,路由静态就是一个过不去的坎。所以,我实际上是通过不同语言下每个路径都有语言前缀来代替了生命周期赋值。这里我可以提供一个切换语言参考的方法,代码如下:

setLang(text){
      var that = this;
      that.$store.commit('SET_LANG', text);
      that.$i18n.locale =text;
      var url = window.location.href;
      var origin   = window.location.origin;
      url = url.replace(origin,"");
      var urlArr = url.split("/");
      var oldLang = urlArr[1];

      var langArr = ['zh','en','jp'];
      if(langArr.indexOf(oldLang)!==-1){
        var urlText = "/"+text+"/";
        var old_urlText = "/"+oldLang+"/";
        url = url.replace(old_urlText,urlText);

      }else{
        url = "/"+text+url;
      }
      localStorage.getItem('lang',text);
      window.location.href=url;
},

这样就可以在页面内容不变的情况下,跳转到对应的语言。

最后

通过上述代码,就可以实现nuxtJS+vue项目的多语言切换。看起来似乎不复杂,但是网上的教程不是表达不清就是缺斤少两,我是真的服了。
如果有疑问可以随时评论留言。

本文来自投稿,不代表本站立场,如若转载,请注明出处:https://www.ruletree.club/archives/3164/
单服务器运行多个RuleApi教程,五分钟搞定
« 上一篇 06-28
通俗易懂理解NuxtJs下Vuex状态树(store) ,实现信息持久化存储实现及管理
下一篇 » 08-30
广告

发表评论

V注册会员 L评论等级
R17 条回复
  1. HGFLv.1 说道:
    2023-08-29     MacOS /    Chrome

    如何在非vue文件内使用多语种呢?比如js文件内

    1. 不暇VLv.6 说道:
      2023-08-31     Win 10 /    Chrome

      @HGF

      很简单啊,你看它是怎么显示在页面的,就在前面加个this,如this.$t('home.title')

      1. HGFLvLv.1 说道:
        2023-09-01     MacOS /    Chrome

        @不暇

        是在js文件内, 没有this,比如我在axios.js内封装axios时候对错误消息的多语种处理该如何引入$t呢

        1. 不暇VLv.6 说道:
          2023-09-05     Win 10 /    Chrome

          @HGFLv

          我记得可以通过参数引入吧,你可以查询一下

  2. SonderLv.1 说道:
    2023-06-25     Win 10 /    Chrome

    用接口怎么来做呢?大佬

  3. 果儿%Lv.1 说道:
    2022-09-27     Win 10 /    Chrome

    请问i18n.js中为什么store.state.locale刷新获取到的值始终是store中locale的初始值?确认已经做了持久化并且生效。

    1. 不暇VLv.6 说道:
      2022-09-27     Android /    Chrome

      @果儿%

      我也遇到过这个问题,可能是持久化插件的bug,因为它终究是基于客户端,暂时没有很好的解决方法,只能是设置一个默认的语言,或者使用服务端的cookies插件。

      1. 果儿%Lv.1 说道:
        2022-09-27     Win 10 /    Chrome

        @不暇

        如果设置了默认的语言,选择了其它语言刷新后就又会变成默认语言呀,我在created中写了this.$i18n.locale = this.$store.state.language.locale 但刷新的时候会闪一下。最后你是怎么解决的呢?

        1. 不暇VLv.6 说道:
          2022-09-27     Android /    Chrome

          @果儿%

          我使用的动态发布,根目录会跳转到默认语言首页,然后项目内所有路径都根据语言变化,所以我不需要在生命周期中对语言进行赋值。

          1. 不暇VLv.6 说道:
            2022-09-27     Android /    Chrome

            @果儿%

            因为这个方法是客户端用的,只能用在生命周期的mounted钩子里。

          2. 果儿%Lv.1 说道:
            2022-09-27     Win 10 /    Chrome

            @不暇

            localStorage.getItem('lang',text) 这儿是不是应该是setItem ,我想过用localStrorage的方式存本地试一试,但是在i18n.js中用locale: localStorage.getItem('locale')中会报localStorage is not defined ,你知道这是为什么吗?

          3. 不暇VLv.6 说道:
            2022-09-27     Android /    Chrome

            @果儿%

            我将文章进行了修改,你可以看一下补充的内容,希望对你有所帮助。

          4. 果儿%Lv.1 说道:
            2022-09-27     Win 10 /    Chrome

            @不暇

            好吧

  4. 果儿%Lv.1 说道:
    2022-09-27     Win 10 /    Chrome

    请问配置generate中routes是为了什么呢?我配置了会导致找不到页面。

    1. 不暇VLv.6 说道:
      2022-09-27     Android /    Chrome

      @果儿%

      这里是取决于你是以静态形式发布还是动态形式发布,因为国际化会自动跳转到语言对应页面,如果你不配置默认需要编译的路由,那么发布之后路径将404。

  5. 卑微页面仔VLv.1 说道:
    2022-08-31     Win 10 /    Chrome

    我以为你的作者后台没有修好,一直在csdn写,恰好今天有人找我骂csdn

    1. 不暇VLv.6 说道:
      2022-08-31     Android /    Chrome

      @卑微页面仔

      ,那或许可以考虑搬运到这里。

没有更多评论了

作者信息

热门文章

标签TAG

热评文章