Nuxt3.x结合i18n国际化

Nuxt3 模块使得i18n更容易与框架结合。
在这里插入图片描述

nuxt/i18n文档 Nuxt3选择i18n的v8版本

一、安装

npm/yarn/pnpm

npm install @nuxtjs/i18n@next --save-dev
yarn add --dev @nuxtjs/i18n@next
pnpm add @nuxtjs/i18n@next --save-dev

二、nuxt.config.ts 中引入模块并配置

// 方式一
export default defineNuxtConfig({
	modules:[...,
	 '@nuxtjs/i18n',
	 ...]
	 i18n:{
	   /*具体配置*/
	 }
})
// 方式二
export default defineNuxtConfig({
	modules:[...,
	 [
	  '@nuxtjs/i18n',
	   {/*具体配置*/}
	 ]
	 ...]
})

案例配置演示

说明:i18n配置中核心翻译配置来源与vueI18n的配置,这里导入同级目录下建立的i18n.config.ts文件

modules: [...,
    '@nuxtjs/i18n',
  ...],
i18n: {
    strategy: 'prefix_and_default', // 添加路由前缀的方式
    locales: ["en","zh","ja"], //配置语种
    defaultLocale: 'en', // 默认语种
    vueI18n: './i18n.config.ts', // 通过vueI18n配置
},

i18n.config.ts

import en from './lang/en.json'
import zh from './lang/zh.json'
import ja from './lang/ja.json'

export default defineI18nConfig(() => ({
    legacy: false,  // 是否兼容之前
    fallbackLocale: 'en',  // 区配不到的语言就用en
    messages: {
        en: en,
        zh: zh,
        ja: ja,
    }
}))

json文件如下,例如:en.json

{
    "home": "Home",
    "test": "Test",
    "about": "About"
}

三、案例测试

1.页面样式

代码

简单安装个elementPlus
yarn add element-plus @element-plus/nuxt -D

一般语言切换都在头部吧,来个头部layouts布局

layouts/default.vue

<template>
    <Header></Header>
    <slot></slot>
</template>

创建components/Header/header.vue

<template>
    <div class="header">
        <div class="headerBox">
            <img src="/favicon.ico" alt="">
            <el-select placeholder="Select">
                <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
            </el-select>
        </div>
        <hr>
    </div>
</template>

<script setup lang='ts'>

const options = [
    {
        value: 'en',
        label: 'English',
    },
    {
        value: 'zh',
        label: '中文',
    },
    {
        value: 'ja',
        label: '日本語',
    },
]
</script>

<style scoped lang="scss">
.header {
    .headerBox {
        display: flex;
        justify-content: space-around;
        align-items: center;
    }
}
</style>

创建主页 pages/index.vue

这里的$t,是安装i18n-nuxt后自动全局引入了在模板中就可以直接用
{{$t(‘json文件属性名’)}}

<template>
    <div class="index">
        {{ $t('home') }}
    </div>
</template>

效果图

目前是这样的一个页面效果,接下来要做的两步
1.切换语言
2.页面跳转

在这里插入图片描述

2.切换语言功能

第一种

配置nuxt.config.ts中的i18n的strategy 为添加路由前缀的方式,通过改变i18n的locale语言跳转到语言前缀页

代码

components/Header/header.vue

此处将el-select 与i18n进行绑定以至于达到改变i18n语言的目的
并且语言改变时触发方法进行页面跳转

<template>
     ...
     <el-select v-model="locale" placeholder="Select" @change="changeLang">
        <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
     </el-select>
     ...
</template>
<script setup lang='ts'>
...
const route = useRoute()
const { locale } = useI18n()

// 语言切换跳转页面
const localeRoute = useLocaleRoute()
const changeLang = async () => {
    // 用于把当前页面生成对应的语言前缀的路由,例如:/zh/,/zh/about
    const routePath = localeRoute({ path: route.fullPath, query: { ...route.query } })
    if (routePath) {
        return navigateTo(routePath.fullPath)  // 路由跳转
    }
}
</script>
效果图

默认是英文界面
在这里插入图片描述
切换成中文,路由跳转/zh
在这里插入图片描述
切换成日文,路由跳转/ja
在这里插入图片描述

第二种

配置nuxt.config.ts中的i18n的strategy为无前缀模式(建议结合cookie存储,否则刷新页面回丢失设置的语言)

代码

pages/setLang.vue

<template>
    <div class="test">
        <a href="#" v-for="lc in locales" :key="(lc as string)" @click.prevent.stop="setLocale(lc as string)">
            {{ lc }}
        </a>
        <br>
        {{ $t('home') }}
    </div>
</template>

<script setup lang='ts'>
const { locale, locales, setLocale } = useI18n()
/* 
   locale 当前i18n的语言 en
   locales i18n中配置的所有语言  {0: 'en', 1: 'zh', 2: 'ja'}
   setLocale 设置i18n语言
   setLocale方法传入所需要跳转语言的string,i18n.config.ts中有配置的语言,这里是通过locale获取到并传入
*/

</script>

<style scoped lang="scss">
.test {
    a {
        margin: 5px;
    }
}
</style>
效果图

在这里插入图片描述
在这里插入图片描述


—2024.03.19更新—

看到评论区有觉得不够详细的地方,随即更新。

这里为什么用无前缀模式呢? 因为是与上面另一种方法做区别,当然如果需要前缀的话,选择其他的路由策略即可

  1. 配置nuxt.config.ts中的i18n的strategy为无前缀模式
i18n: {
   strategy: 'no_prefix', // 添加路由前缀的方式
   locales: ["en", "zh", "ja"], //配置语种
   defaultLocale: 'en', // 默认语种
   vueI18n: './i18n.config.ts', // 通过vueI18n配置
 },
  1. 通过之前的配置默认情况下语言已经会存入cookie中了 useCookie的值默认为true ,如果需要在i18n.config.ts中配置即可

在这里插入图片描述
在这里插入图片描述
完成了无显示语言路由且刷新不会丢失语言。

3.页面间跳转

问题

按照原先Nuxt的跳转写法NuxtLink会存在问题,跳转会丢失当前语言路由

pages/index.vue

<template>
    <div class="index">
        {{ $t('home') }}
        <NuxtLink to="/about">{{ $t('about') }}</NuxtLink>
    </div>
</template>

pages/about.vue

<template>
  <div class="about">
    {{ $t('about') }}
    <NuxtLink to="/">{{ $t('home') }}</NuxtLink>
  </div>
</template>

解决

用i18n提供的NuxtLinkLocale替代NuxtLink

<template>
 <div class="index">
        {{ $t('home') }}
        <NuxtLinkLocale to="/about">{{ $t('about') }}</NuxtLinkLocale>
 </div>
</template>

NuxtLinkLocale本质调用了localeRoute(),故也可

<template>
 <div class="index">
        {{ $t('home') }}
        <NuxtLink :to="localePath('/about')">{{ $t('about') }}</NuxtLink>
 </div>
</template>
<script setup lang='ts'>
	const localePath = useLocalePath()
</script>

效果图

在这里插入图片描述
在这里插入图片描述

以上

相关配置

可以根据自己项目需要,选择是否增添语言路由前缀
路由前缀
可以选择首次进入是否按浏览器默认语言以及cookie存储上次语言
设置浏览器默认语言
懒加载,排除国际化页面、SEO、页面单独配置i18n等等更多配置请参考官方文档
nuxt/i18n文档

Logo

前往低代码交流专区

更多推荐