Angular多语言支持保姆级教程:从配置到部署一步搞定国际化

Angular多语言支持保姆级教程:从配置到部署一步搞定国际化 一

文章目录CloseOpen

准备工作:Angular多语言环境搭起来

先别急着写代码,环境搭不对,后面全白费。我吃过这亏,之前用 Angular 8 做项目,当时还没有内置的多语言模块,得自己装 @angular/localize,现在 Angular 14+ 已经默认集成了,省事儿不少。不过不同版本的配置有点区别,先给你捋捋:

先看你的 Angular 版本

如果你的项目是 Angular 9 及以上,直接用官方的 @angular/localize 模块就行;要是 Angular 8 及以下,得先手动安装依赖。我整理了个表格,你对着看:

Angular 版本 @angular/localize 支持 操作步骤
8 及以下 需手动安装 npm install @angular/localize save
9-13 内置但需启用 ng add @angular/localize
14+ 默认集成 无需额外操作

安装完依赖,接下来要改 angular.json 文件。打开这个文件,找到 projects -> 你的项目名 -> architect -> build -> options,加一行 "localize": true,这一步是告诉 Angular “我们要开启多语言模式啦”。然后在 options 里再加个 i18nMissingTranslation 配置,设为 warning,这样如果有没翻译的内容,编译时会提醒你,不至于上线后才发现漏翻了。

对了,翻译文件放哪儿也很重要。 在 src 目录下建个 locale 文件夹,专门放各国语言的翻译文件,比如 messages.en.xlf(英文)、messages.ja.xlf(日文),这样后期维护一目了然。我之前见过有人把翻译文件散落在各个组件里,后来要改个翻译,找文件找了半小时,血的教训啊。

实战开发:从标记到动态切换全流程

环境搭好了,接下来就是正经开发了。这部分分三步走,每一步都有坑,我会把我踩过的坑提前告诉你,省得你重蹈覆辙。

第一步:给页面内容打上 i18n 标记

所有要翻译的文字,都得在模板里加上 i18n 属性,比如页面标题、按钮文字、提示信息。举个例子,你原来的模板可能是这样的:

欢迎来到我的应用

当前时间:2023年10月15日

现在要改成带 i18n 标记的版本:

欢迎来到我的应用

当前时间:{{ today | date }}

这里有个细节,i18n 后面可以加个描述,方便翻译人员理解语境。比如按钮上的“点击购买”,可以写成 @@buyButton 是这个翻译的唯一标识,后面生成翻译文件时会用到。我之前做金融项目,“平仓”这个词在不同场景有不同意思,加了标识后,翻译人员就知道这里是“交易平仓”而不是“仓库平仓”,避免了歧义。

第二步:生成翻译文件并填充内容

标记打好了,就该生成翻译文件了。在终端里跑命令:ng extract-i18n output-path src/locale format xlfformat xlf 是指定用 XLIFF 格式(一种常见的翻译文件格式),Angular 也支持 XMB 格式,但 XLIFF 更通用,翻译工具基本都支持。

跑完命令,src/locale 文件夹里会多出一个 messages.xlf 文件,打开看看,里面长这样:


点击购买

source

里是原文(中文),target 就是要填翻译的地方。接下来复制一份 messages.xlf,改名叫 messages.en.xlf,然后把 target 里的内容换成英文:Buy Now。其他语言依葫芦画瓢就行。

这里有个坑要注意:翻译文件里的 id 必须和模板里的 @@标识 对应,不然翻译不生效。我之前有个页面,明明标记和翻译都写了,结果显示的还是中文,查了半天才发现是复制文件时,id 不小心改了,血的教训+1。

第三步:实现语言动态切换功能

最关键的一步来了——怎么让用户自己切换语言?Angular 有两种方案:编译时多语言和运行时多语言。

编译时多语言是给每种语言单独构建一个包,比如中文包、英文包,用户切换语言时跳转到对应包的 URL(比如 /en/ja)。这种方式性能好,加载快,但缺点是切换语言要刷新页面。适合语言版本差异大、对性能要求高的项目,比如电商网站。配置方法也简单,在 angular.jsonconfigurations 里加语言配置,然后用 ng build configuration=production,en 构建英文包。

如果你想不刷新页面切换语言(比如后台管理系统,用户体验要求高),就得用运行时切换。这时候要用到 @angular/localizeloadTranslations 函数,或者第三方库 @ngx-translate/core。我个人更推荐 @ngx-translate,用法简单,还支持异步加载翻译文件。

举个 @ngx-translate 的例子:先安装依赖 npm install @ngx-translate/core @ngx-translate/http-loader save,然后在 app.module.ts 里导入模块:

import { TranslateModule, TranslateLoader } from '@ngx-translate/core';

import { TranslateHttpLoader } from '@ngx-translate/http-loader';

import { HttpClient } from '@angular/common/http';

// 加载翻译文件

export function HttpLoaderFactory(http: HttpClient) {

return new TranslateHttpLoader(http, './assets/i18n/', '.json');

}

@NgModule({

imports: [

TranslateModule.forRoot({

loader: {

provide: TranslateLoader,

useFactory: HttpLoaderFactory,

deps: [HttpClient]

}

})

]

})

然后在组件里注入 TranslateService,调用 use 方法切换语言:

constructor(private translate: TranslateService) {

// 设置默认语言

translate.setDefaultLang('zh');

}

switchLanguage(lang: string) {

this.translate.use(lang); // 传入 'en' 就切换到英文,无需刷新页面

}

模板里用 translate 管道显示翻译内容:

{{ 'welcome' | translate }}

是不是超简单?不过要注意,@ngx-translate 用的是 JSON 翻译文件,所以之前的 XLF 文件要转成 JSON 格式,网上有在线转换工具,搜“xlf to json”就行。

处理特殊格式也是个大头,比如日期、货币、复数。就说复数吧,中文里“1条消息”和“5条消息”差别不大,但英文里“1 message”和“5 messages”就得变复数。这时候别自己写 if-else 判断,Angular 的 ICU 消息格式直接搞定:

{count, plural,

=0 {没有新消息}

=1 {1条新消息}

other {{{count}}条新消息}

}

count

是你定义的数量变量,这样不管数字是多少,翻译都会自动适配。我之前做社交 app,消息提示就用的这个,支持了10多种语言,从没出过格式问题。

对了,日期和货币格式化要记得注入 LOCALE_ID。在模块里 providers 里加 { provide: LOCALE_ID, useValue: 'en-US' },就能让 date 管道显示英文日期格式(比如 MM/dd/yyyy)。如果是动态切换语言,就用 TranslateServiceonLangChange 事件,动态更新 LOCALE_ID,这个稍微复杂点,你可以先记着,遇到了再查官方文档(https://angular.io/guide/i18n-common-locale-id nofollow),写得很详细。

你跟着这些步骤走,基本就能搞定 Angular 多语言支持了。对了,记得用 ng serve configuration=en 测试英文版本,别等上线了才发现翻译文件路径写错了。如果遇到翻译不生效的情况,先检查 i18n 标记有没有漏加,再看看翻译文件的 id 对不对,90%的问题都出在这俩地方。你要是试了这套流程,欢迎回来告诉我效果,或者有啥卡壳的地方,咱们一起琢磨琢磨~


不刷新页面切换语言啊,我推荐你试试运行时切换方案,这可比编译时那种每次切换都要刷新页面的方式友好多了。之前我做一个跨境电商后台,一开始用的编译时方案,用户切换语言就得重新加载整个页面,表单填一半切换语言,内容全没了,被吐槽了好多次。后来换成运行时方案,体验直接上了个台阶。

具体操作的话,最常用的就是第三方库@ngx-translate/core,这玩意儿社区活跃,文档也全,出了问题也好找解决办法。你先得把两个依赖装上:@ngx-translate/core和@ngx-translate/http-loader,用npm install命令就行。装完之后,得在根模块里配置一下翻译文件的加载路径,一般我会把翻译文件放在src/assets/i18n目录下,比如英文是en.json,日文是ja.json,这样路径就写成’./assets/i18n/’,后缀是’.json’。这里有个小坑,路径千万别写错,之前我把assets写成asset少个s,结果翻译文件一直加载失败,调试半天才发现是拼写问题。

配置好之后,在组件里注入TranslateService,然后调用它的use()方法就能切换语言了,比如想切英文就this.translate.use(‘en’),日语就传’ja’,完全不用刷新页面。我一般会在页面顶部放个语言选择下拉框,用户选完直接触发这个方法,整个页面的文字就实时变了,特别丝滑。这种方式尤其适合后台管理系统、SaaS平台这类需要频繁切换语言的场景,用户操作流程不会被打断,体验感会好很多。

而且@ngx-translate还有个好处是支持异步加载翻译文件,就是说不是一上来就把所有语言包都塞给用户,而是用户切换到哪个语言,才去加载对应语言的翻译文件,对首屏加载速度挺友好的。之前做个多语言项目,光英文翻译文件就有500多KB,用异步加载后,首屏加载快了近2秒,用户反馈明显好了不少。如果你项目比较大,翻译内容多,这个点一定要用上,能省不少加载时间。


Angular 8及以下版本如何启用多语言支持?

Angular 8及以下版本需要手动安装@angular/localize依赖,执行命令“npm install @angular/localize save”即可。安装后在angular.json文件中配置“localize: true”,并 设置“i18nMissingTranslation: warning”以便编译时提醒未翻译内容。翻译文件推荐放在src/locale目录下,方便统一管理。

翻译文件只能用XLIFF格式吗?

不是的,Angular支持多种翻译文件格式,除了文章中提到的XLIFF(.xlf),还支持XMB(.xmb)和ARB(.arb)格式。XLIFF是最通用的选择,大部分翻译工具(如Poedit、Trados)都支持;ARB格式更简洁,适合小型项目;XMB则是Angular早期使用的格式,现在较少推荐。实际开发中可根据团队习惯和翻译工具选择, 优先用XLIFF保证兼容性。

不刷新页面切换语言的话,用什么方案最合适?

推荐用运行时切换方案,最常用的是借助第三方库@ngx-translate/core。它支持异步加载JSON格式的翻译文件,调用TranslateService的use()方法即可动态切换语言,无需刷新页面。具体步骤:先安装@ngx-translate/core和@ngx-translate/http-loader,配置翻译文件加载路径,然后在组件中注入TranslateService,通过按钮点击等事件触发语言切换。这种方式对用户体验更友好,尤其适合后台管理系统等需要频繁切换语言的场景。

处理复数、日期等特殊格式时,有哪些避坑点?

主要注意两点:一是复数规则用ICU消息格式,避免手动写if-else判断,比如“{count, plural, =0 {没有消息} =1 {1条消息} other {{{count}}条消息}}”,Angular会自动根据count值适配不同语言的复数形式;二是日期、货币等格式化需注入LOCALE_ID,在模块providers中配置“{ provide: LOCALE_ID, useValue: ‘en-US’ }”即可切换对应地区格式。动态切换语言时,可监听TranslateService的onLangChange事件,实时更新LOCALE_ID值,确保格式与当前语言匹配。

多语言项目如何优化加载性能?

可以从三个方面优化:一是采用“按需加载”,通过@ngx-translate/http-loader只加载当前语言的翻译文件,避免一次性加载所有语言包;二是压缩翻译文件,用在线工具将JSON/XLIFF文件压缩后再部署,减少网络传输体积;三是生产环境构建时启用AOT编译(ng build prod),Angular会对翻译内容进行预编译,提升渲染速度。 避免在翻译文件中存放大量冗余文本,只保留必要的页面文案,也能有效减小文件体积。

0
显示验证码
没有账号?注册  忘记密码?