Nuxt.js ---- 基于 Vue.js 的服务端渲染应用框架(实战篇四)

学习目标:

1.利用vue-i18n实现国际化


完整代码请点击下方链接前往git获取:

git项目地址


一.引入库

代码如下(示例):

//npm 
npm install vue-i18n@8.9.0 --save-dev

//yarn
yarn add vue-i18n@8.9.0

2.在locales文件夹创建 en.json 和 zh.json

代码如下(示例):

//en.json文件
{
  "language": "Language",
  "languages": "EN",
  "login": "Login",
  "nav-bar": {
    "searchtip": "Search",
    "promotion": "Promotion cooperation",
    "join":"Joining us"
  }
}

//zh.json文件
{
  "language": "语言",
  "languages": "中文",
  "login":"登录",
  "nav-bar": {
    "searchtip": "关键字搜索",
    "promotion": "推广合作",
    "join":"申请加盟"
  }
}

三.创建i18n.js

plugins目录下,创建该文件

代码如下(示例):

//i18n.js 文件

import Vue from 'vue';
import VueI18n from 'vue-i18n';
Vue.use(VueI18n);

export default ({ app, store }) => {
  // Set i18n instance on app
  // This way we can use it in middleware and pages asyncData/fetch
  app.i18n = new VueI18n({
    locale: store.state.locale,
    fallbackLocale: 'zh',
    messages: {
      'en': require('~/locales/en.json'),
      'zh': require('~/locales/zh.json')
    }
  });
  
}

四.创建中间件

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) {
        if (req.headers['accept-language']) {
          locale = req.headers['accept-language'].split(',')[0].toLocaleLowerCase().substring(0, 2);
        } else {
          locale = "zh"
        }
      }

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

五.添加到nuxt.config.js

如下图:

在这里插入图片描述

六. 创建语言切换的组件,并放在nav-bar组件中

代码如下(示例):

//SwitchLang.vue

<template>
  <div class="language" @click.stop>
    <div class="language-div hor-center slgap" @click="langed = !langed">
      <div class="body1" :class="{ 'body-langed': langed }">
        {{ $t("languages") }}
      </div>
      <img
        src="@/assets/common/chevronDown.svg"
        class="language-img"
        :class="{ 'img-rotate': langed }"
      />
      <div class="line"></div>
    </div>

    <div class="language-box col" :class="{ 'language-hidden': !langed }">
      <div
        class="language-label flex"
        v-for="(lang, i) in locales"
        :key="i"
        @click="switchLanguage(lang.code)"
      >
        {{ lang.name }}
      </div>
    </div>
  </div>
</template>

<script>
export default {
  head() {
    return {
      htmlAttrs: {
        lang: this.$store.state.locale,
      },
    };
  },
  name: "SwitchLang",
  data() {
    return {
      langed: false,
    };
  },
  methods: {
    switchLanguage(localeCode) {
      document.cookie = `locale=${localeCode}`;
      location.reload();
    },
    closeCompsAction() {
      this.langed = false;
    },
  },
  computed: {
    locales() {
      return this.$store.state.locales;
    },
    locale() {
      return this.$store.state.locale;
    },
  },
  created() {
    this.$EventBus.$on("closeComps", this.closeCompsAction);
  },
  beforeDestroy() {
    this.$EventBus.$off("closeComps",this.closeCompsAction);
  },
};
</script>

<style scoped>
.language {
  cursor: pointer;
}

.body1 {
  font-size: 15px;
  width: 50px;
  color: #5d6175;
  text-align: right;
}
.body1,
.language-img {
  opacity: 0.8;
  transition: all 0.3s;
}
.language-div:hover .body1,
.language-div:hover .language-img {
  opacity: 1;
}
.img-rotate {
  transform: rotate(-180deg);
}
.body-langed {
  opacity: 1;
}

.language-box {
  position: absolute;
  z-index: 99;
  margin: 5px 0 0 -35px;
  background-color: white;
  border-radius: 8px;
  box-shadow: 0px 10px 40px rgba(56, 66, 104, 0.1);
  opacity: 1;
  transform: translateY(0px);
  transition: opacity 0.2s linear, visibility 0.2s, transform 0.4s;
}
.language-hidden {
  pointer-events: none;
  transform: translateY(-10px);
  visibility: hidden;
  opacity: 0;
}
.language-label {
  justify-content: flex-end;
  padding: 15px 30px;
  border-radius: 8px;
   color: #5d6175;
  opacity: 0.8;
}
.language-label:hover {
  background-color: whitesmoke;
  opacity: 1;
}
.line{
  width: 1px;
  height: 20px;
  background: #e5e7eb;
  margin-left: 15px;
}
</style>

六. 在页面中使用

代码如下(示例和效果图):


 <div class="label" @click="tip()">{{ $t("nav-bar.promotion") }}</div>
 
 <div class="label" @click="go('/apply')">{{ $t("nav-bar.join") }}</div>

效果图:

当前语言:中文

在这里插入图片描述


当前语言:English

在这里插入图片描述

到这里就已经介绍完了。


总结:

1.使用vue-i18n国际化库的时候,在Nuxt中需要做的配置会比在Vue中多一些,记得不要漏了加在nuxt.config.js中

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

彭式程序猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值