Nuxt.js 国际化支持
国际化(Internationalization,简称 i18n)是现代前端应用的重要功能之一,它允许应用支持多种语言和地区设置,为全球用户提供更好的用户体验。Nuxt.js 提供了完善的国际化支持,使开发者能够轻松构建多语言应用。本章节将详细介绍 Nuxt.js 的国际化功能,包括配置、使用方法和最佳实践。
1. 国际化的重要性
1.1 什么是国际化
国际化是指设计和开发应用时,使其能够适应不同语言和地区的需求,而不需要对代码进行重大修改。国际化的目标是让应用能够无缝地支持多种语言和地区设置。
1.2 国际化的重要性
- 全球用户:支持多种语言可以吸引全球用户,扩大应用的受众范围
- 用户体验:使用用户的母语可以提供更好的用户体验,增加用户满意度
- 市场竞争力:国际化的应用在全球市场中更具竞争力
- 合规要求:某些地区可能要求应用提供本地语言支持
1.3 国际化与本地化的区别
- 国际化(i18n):设计和开发应用时,使其能够适应不同语言和地区的需求
- 本地化(l10n):将国际化的应用适配到特定语言和地区的过程,包括翻译文本、调整日期格式、货币单位等
2. Nuxt.js 国际化模块
Nuxt.js 官方推荐使用 @nuxtjs/i18n 模块来实现国际化功能。这个模块基于 Vue I18n 库,提供了完善的国际化支持。
2.1 安装国际化模块
npm install @nuxtjs/i18n2.2 基本配置
在 nuxt.config.js 文件中配置 @nuxtjs/i18n 模块:
export default {
modules: [
'@nuxtjs/i18n'
],
i18n: {
// 配置选项
locales: [
{ code: 'en', iso: 'en-US', name: 'English' },
{ code: 'zh', iso: 'zh-CN', name: '中文' }
],
defaultLocale: 'zh',
vueI18n: {
fallbackLocale: 'zh',
messages: {
en: {
welcome: 'Welcome to Nuxt.js!',
about: 'About Us',
contact: 'Contact Us'
},
zh: {
welcome: '欢迎使用 Nuxt.js!',
about: '关于我们',
contact: '联系我们'
}
}
}
}
}2.3 配置选项详解
2.3.1 基本配置
- locales:语言列表,每个语言包含 code(语言代码)、iso(ISO 语言代码)和 name(语言名称)
- defaultLocale:默认语言
- vueI18n:Vue I18n 配置,包含 fallbackLocale(回退语言)和 messages(语言消息)
2.3.2 高级配置
export default {
i18n: {
// 语言列表
locales: [
{ code: 'en', iso: 'en-US', name: 'English', file: 'en.js' },
{ code: 'zh', iso: 'zh-CN', name: '中文', file: 'zh.js' }
],
// 默认语言
defaultLocale: 'zh',
// 语言文件目录
langDir: 'lang/',
// 回退语言
fallbackLocale: 'zh',
// 路由国际化
strategy: 'prefix_except_default',
// 检测浏览器语言
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
onlyOnRoot: true
},
// seo 优化
vueI18n: {
fallbackLocale: 'zh',
messages: {
en: {
welcome: 'Welcome to Nuxt.js!'
},
zh: {
welcome: '欢迎使用 Nuxt.js!'
}
}
}
}
}3. 语言文件管理
3.1 语言文件结构
对于大型应用,建议将语言消息存储在单独的文件中,而不是直接在配置文件中定义。
3.1.1 目录结构
lang/
├── en.js
└── zh.js3.1.2 语言文件内容
// lang/en.js
export default {
welcome: 'Welcome to Nuxt.js!',
about: 'About Us',
contact: 'Contact Us',
navigation: {
home: 'Home',
blog: 'Blog',
products: 'Products'
},
buttons: {
submit: 'Submit',
cancel: 'Cancel',
save: 'Save'
}
}
// lang/zh.js
export default {
welcome: '欢迎使用 Nuxt.js!',
about: '关于我们',
contact: '联系我们',
navigation: {
home: '首页',
blog: '博客',
products: '产品'
},
buttons: {
submit: '提交',
cancel: '取消',
save: '保存'
}
}3.2 语言文件配置
在 nuxt.config.js 文件中配置语言文件目录:
export default {
i18n: {
locales: [
{ code: 'en', iso: 'en-US', name: 'English', file: 'en.js' },
{ code: 'zh', iso: 'zh-CN', name: '中文', file: 'zh.js' }
],
langDir: 'lang/',
defaultLocale: 'zh'
}
}4. 在应用中使用国际化
4.1 在模板中使用
在 Vue 模板中,可以使用 $t 方法来翻译文本:
<template>
<div>
<h1>{{ $t('welcome') }}</h1>
<nav>
<ul>
<li><nuxt-link to="/" {{ $t('navigation.home') }}</nuxt-link></li>
<li><nuxt-link to="/blog" {{ $t('navigation.blog') }}</nuxt-link></li>
<li><nuxt-link to="/products" {{ $t('navigation.products') }}</nuxt-link></li>
</ul>
</nav>
<button>{{ $t('buttons.submit') }}</button>
</div>
</template>4.2 在脚本中使用
在 Vue 脚本中,可以使用 this.$t 方法来翻译文本:
<script>
export default {
data() {
return {
message: this.$t('welcome')
}
},
methods: {
showMessage() {
alert(this.$t('welcome'))
}
}
}
</script>4.3 在组件中使用
在组件中使用国际化:
<template>
<div>
<h2>{{ $t('about') }}</h2>
<p>{{ $t('aboutDescription') }}</p>
</div>
</template>
<script>
export default {
mounted() {
console.log(this.$t('about'))
}
}
</script>4.4 在页面中使用
在页面组件中使用国际化:
<template>
<div>
<h1>{{ $t('welcome') }}</h1>
<p>{{ $t('description') }}</p>
</div>
</template>
<script>
export default {
async asyncData({ app }) {
// 在 asyncData 中使用国际化
const title = app.i18n.t('welcome')
return { title }
}
}
</script>4.5 在插件中使用
在插件中使用国际化:
export default function({ app }) {
// 在插件中使用国际化
console.log(app.i18n.t('welcome'))
}4.6 在中间件中使用
在中间件中使用国际化:
export default function({ app }) {
// 在中间件中使用国际化
console.log(app.i18n.t('welcome'))
}5. 动态语言切换
5.1 语言切换方法
Nuxt.js 的国际化模块提供了 $i18n 对象,通过它可以切换语言:
<template>
<div>
<div class="language-switcher">
<button @click="switchLanguage('zh')" :class="{ active: $i18n.locale === 'zh' }">中文</button>
<button @click="switchLanguage('en')" :class="{ active: $i18n.locale === 'en' }">English</button>
</div>
<h1>{{ $t('welcome') }}</h1>
</div>
</template>
<script>
export default {
methods: {
switchLanguage(lang) {
this.$i18n.locale = lang
}
}
}
</script>
<style scoped>
.language-switcher {
margin-bottom: 20px;
}
.language-switcher button {
padding: 8px 16px;
margin-right: 10px;
border: 1px solid #ddd;
background-color: #f0f0f0;
cursor: pointer;
}
.language-switcher button.active {
background-color: #007bff;
color: white;
border-color: #007bff;
}
</style>5.2 语言切换的高级用法
5.2.1 带参数的语言切换
<template>
<div>
<div class="language-switcher">
<button
v-for="locale in $i18n.locales"
:key="locale.code"
@click="switchLanguage(locale.code)"
:class="{ active: $i18n.locale === locale.code }"
>
{{ locale.name }}
</button>
</div>
</div>
</template>
<script>
export default {
methods: {
switchLanguage(lang) {
this.$i18n.locale = lang
}
}
}
</script>5.2.2 语言切换时的路由处理
当切换语言时,Nuxt.js 的国际化模块会自动处理路由:
- prefix_except_default 策略:默认语言没有前缀,其他语言有前缀
- prefix 策略:所有语言都有前缀
- no_prefix 策略:所有语言都没有前缀,通过其他方式区分
6. 国际化的高级特性
6.1 翻译参数
可以在翻译文本中使用参数:
// lang/en.js
export default {
welcome: 'Welcome, {name}!',
items: 'You have {count} items'
}
// lang/zh.js
export default {
welcome: '欢迎,{name}!',
items: '你有 {count} 个项目'
}在模板中使用参数:
<template>
<div>
<h1>{{ $t('welcome', { name: 'John' }) }}</h1>
<p>{{ $t('items', { count: 5 }) }}</p>
</div>
</template>6.2 复数形式
可以处理复数形式的翻译:
// lang/en.js
export default {
item: 'item | items'
}
// lang/zh.js
export default {
item: '项目'
}在模板中使用复数形式:
<template>
<div>
<p>{{ $tc('item', 1) }}</p> <!-- 输出:item -->
<p>{{ $tc('item', 5) }}</p> <!-- 输出:items -->
</div>
</template>6.3 日期和时间格式化
可以格式化日期和时间:
// lang/en.js
export default {
date: {
format: 'MM/DD/YYYY'
}
}
// lang/zh.js
export default {
date: {
format: 'YYYY年MM月DD日'
}
}在模板中使用日期格式化:
<template>
<div>
<p>{{ $d(new Date(), 'date.format') }}</p>
</div>
</template>6.4 数字格式化
可以格式化数字:
// lang/en.js
export default {
number: {
currency: 'USD'
}
}
// lang/zh.js
export default {
number: {
currency: 'CNY'
}
}在模板中使用数字格式化:
<template>
<div>
<p>{{ $n(1234.56, 'currency') }}</p>
</div>
</template>6.5 区域设置
可以设置区域特定的格式:
export default {
i18n: {
locales: [
{ code: 'en', iso: 'en-US', name: 'English', file: 'en.js' },
{ code: 'zh', iso: 'zh-CN', name: '中文', file: 'zh.js' }
],
defaultLocale: 'zh',
langDir: 'lang/',
vueI18n: {
fallbackLocale: 'zh',
locale: 'zh',
messages: {
en: {
// 英文翻译
},
zh: {
// 中文翻译
}
},
numberFormats: {
en: {
currency: {
style: 'currency',
currency: 'USD'
}
},
zh: {
currency: {
style: 'currency',
currency: 'CNY'
}
}
},
dateTimeFormats: {
en: {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
}
},
zh: {
short: {
year: 'numeric',
month: 'short',
day: 'numeric'
}
}
}
}
}
}7. 路由国际化
7.1 路由国际化策略
Nuxt.js 的国际化模块支持多种路由国际化策略:
- prefix_except_default:默认语言没有前缀,其他语言有前缀(推荐)
- prefix:所有语言都有前缀
- no_prefix:所有语言都没有前缀,通过其他方式区分
7.2 配置路由国际化
export default {
i18n: {
strategy: 'prefix_except_default',
locales: [
{ code: 'en', iso: 'en-US', name: 'English' },
{ code: 'zh', iso: 'zh-CN', name: '中文' }
],
defaultLocale: 'zh'
}
}7.3 生成国际化路由
Nuxt.js 的国际化模块会自动为每个语言生成对应的路由:
- 默认语言(中文):
/、/about、/contact - 其他语言(英文):
/en/、/en/about、/en/contact
7.4 路由参数国际化
可以为路由参数提供国际化支持:
<template>
<div>
<h1>{{ $t('productTitle', { id: $route.params.id }) }}</h1>
</div>
</template>
<script>
export default {
async asyncData({ params, app }) {
const product = await fetchProduct(params.id)
return { product }
}
}
</script>8. SEO 优化
8.1 国际化与 SEO
国际化的应用需要考虑 SEO 优化,确保不同语言版本的页面都能被搜索引擎正确索引。
8.2 配置 SEO 优化
export default {
i18n: {
seo: true,
locales: [
{ code: 'en', iso: 'en-US', name: 'English' },
{ code: 'zh', iso: 'zh-CN', name: '中文' }
],
defaultLocale: 'zh'
}
}8.3 hreflang 标签
Nuxt.js 的国际化模块会自动生成 hreflang 标签,帮助搜索引擎理解页面的语言和地区:
<link rel="alternate" hreflang="zh" href="https://example.com/" />
<link rel="alternate" hreflang="en" href="https://example.com/en/" />8.4 页面标题和描述国际化
可以为不同语言设置不同的页面标题和描述:
<template>
<div>
<h1>{{ $t('welcome') }}</h1>
</div>
</template>
<script>
export default {
head() {
return {
title: this.$t('pageTitle'),
meta: [
{
hid: 'description',
name: 'description',
content: this.$t('pageDescription')
}
]
}
}
}
</script>9. 国际化的最佳实践
9.1 组织翻译文件
- 按功能模块组织:将翻译文件按功能模块组织,便于管理
- 使用命名空间:使用命名空间来组织翻译文本,避免命名冲突
- 保持一致性:保持翻译文本的一致性,使用相同的术语
- 使用工具管理:使用专业的翻译管理工具来管理翻译文本
9.2 性能优化
- 懒加载语言文件:只加载当前语言的文件,减少初始加载时间
- 缓存翻译:缓存翻译结果,减少重复计算
- 按需加载:按需加载翻译文件,避免一次性加载所有语言文件
9.3 开发流程
- 翻译键命名规范:使用一致的命名规范,如
module.feature.action - 占位符使用:使用占位符而不是硬编码文本
- 注释:为复杂的翻译文本添加注释,便于翻译人员理解
- 测试:测试不同语言版本的应用,确保所有文本都能正确显示
9.4 常见问题
- 文本长度:不同语言的文本长度可能不同,需要考虑布局适配
- 日期和时间格式:不同地区的日期和时间格式可能不同
- 货币单位:不同地区的货币单位可能不同
- 方向:某些语言(如阿拉伯语)是从右到左书写的,需要考虑布局适配
10. 实际项目示例
10.1 完整的国际化配置
// nuxt.config.js
export default {
modules: [
'@nuxtjs/i18n'
],
i18n: {
locales: [
{ code: 'en', iso: 'en-US', name: 'English', file: 'en.js' },
{ code: 'zh', iso: 'zh-CN', name: '中文', file: 'zh.js' }
],
defaultLocale: 'zh',
langDir: 'lang/',
strategy: 'prefix_except_default',
detectBrowserLanguage: {
useCookie: true,
cookieKey: 'i18n_redirected',
onlyOnRoot: true
},
vueI18n: {
fallbackLocale: 'zh'
}
}
}10.2 语言文件示例
// lang/en.js
export default {
common: {
welcome: 'Welcome to Nuxt.js!',
about: 'About Us',
contact: 'Contact Us'
},
navigation: {
home: 'Home',
blog: 'Blog',
products: 'Products',
services: 'Services'
},
buttons: {
submit: 'Submit',
cancel: 'Cancel',
save: 'Save',
delete: 'Delete'
},
errors: {
required: '{field} is required',
minLength: '{field} must be at least {min} characters',
maxLength: '{field} must be at most {max} characters'
}
}
// lang/zh.js
export default {
common: {
welcome: '欢迎使用 Nuxt.js!',
about: '关于我们',
contact: '联系我们'
},
navigation: {
home: '首页',
blog: '博客',
products: '产品',
services: '服务'
},
buttons: {
submit: '提交',
cancel: '取消',
save: '保存',
delete: '删除'
},
errors: {
required: '{field} 是必填项',
minLength: '{field} 至少需要 {min} 个字符',
maxLength: '{field} 最多只能有 {max} 个字符'
}
}10.3 组件示例
<template>
<div>
<div class="language-switcher">
<button
v-for="locale in $i18n.locales"
:key="locale.code"
@click="switchLanguage(locale.code)"
:class="{ active: $i18n.locale === locale.code }"
>
{{ locale.name }}
</button>
</div>
<nav>
<ul>
<li><nuxt-link to="/" {{ $t('navigation.home') }}</nuxt-link></li>
<li><nuxt-link to="/about" {{ $t('navigation.about') }}</nuxt-link></li>
<li><nuxt-link to="/products" {{ $t('navigation.products') }}</nuxt-link></li>
<li><nuxt-link to="/services" {{ $t('navigation.services') }}</nuxt-link></li>
</ul>
</nav>
<h1>{{ $t('common.welcome') }}</h1>
<form>
<div>
<label for="name">{{ $t('form.name') }}</label>
<input type="text" id="name" v-model="name">
<p v-if="!name" class="error">{{ $t('errors.required', { field: $t('form.name') }) }}</p>
</div>
<div>
<button type="button" @click="submitForm">{{ $t('buttons.submit') }}</button>
<button type="button" @click="cancelForm">{{ $t('buttons.cancel') }}</button>
</div>
</form>
</div>
</template>
<script>
export default {
data() {
return {
name: ''
}
},
methods: {
switchLanguage(lang) {
this.$i18n.locale = lang
},
submitForm() {
// 提交表单
},
cancelForm() {
// 取消表单
}
}
}
</script>
<style scoped>
.language-switcher {
margin-bottom: 20px;
}
.language-switcher button {
padding: 8px 16px;
margin-right: 10px;
border: 1px solid #ddd;
background-color: #f0f0f0;
cursor: pointer;
}
.language-switcher button.active {
background-color: #007bff;
color: white;
border-color: #007bff;
}
nav ul {
list-style: none;
padding: 0;
display: flex;
gap: 20px;
margin-bottom: 30px;
}
nav a {
text-decoration: none;
color: #333;
}
form {
max-width: 500px;
}
form div {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
}
input {
width: 100%;
padding: 8px;
border: 1px solid #ddd;
border-radius: 4px;
}
.error {
color: #dc3545;
font-size: 0.8em;
margin-top: 5px;
}
button {
padding: 8px 16px;
margin-right: 10px;
border: 1px solid #ddd;
border-radius: 4px;
background-color: #f8f9fa;
cursor: pointer;
}
button:hover {
background-color: #e9ecef;
}
</style>11. 总结
本章节介绍了 Nuxt.js 的国际化支持,包括:
国际化的重要性:全球用户、用户体验、市场竞争力、合规要求
Nuxt.js 国际化模块:
- 安装和配置
- 配置选项详解
语言文件管理:
- 语言文件结构
- 语言文件配置
在应用中使用国际化:
- 在模板中使用
- 在脚本中使用
- 在组件中使用
- 在页面中使用
- 在插件中使用
- 在中间件中使用
动态语言切换:
- 语言切换方法
- 语言切换时的路由处理
国际化的高级特性:
- 翻译参数
- 复数形式
- 日期和时间格式化
- 数字格式化
- 区域设置
路由国际化:
- 路由国际化策略
- 生成国际化路由
- 路由参数国际化
SEO 优化:
- 国际化与 SEO
- 配置 SEO 优化
- hreflang 标签
- 页面标题和描述国际化
国际化的最佳实践:
- 组织翻译文件
- 性能优化
- 开发流程
- 常见问题
实际项目示例:
- 完整的国际化配置
- 语言文件示例
- 组件示例
通过本章节的学习,你应该能够在 Nuxt.js 项目中实现完善的国际化功能,为全球用户提供更好的用户体验。国际化是一个持续的过程,需要不断完善和优化,以适应不同语言和地区的需求。