前言
有时候,我们开发了一个项目,需要走国际化。那么我们需要设置多国语言。下面,我们以 Angular
项目为例,说说怎么针对 Angular
项目来设置多国语言。React
和 Vue
项目同理~
这里我们仅考虑简体中文和美国英文两种语言,使用的框架版本为 @angular/core: "~12.1.0"
在日常开发中,我们难免会引入第三方 UI
框架,那么这就涉及了第三方 UI
框架的多国语言和自定义的多国语言了。下面我们进入主题~
如何判断语言
怎么知道我们所处的语言环境呢?
这里我们采用两种方式:
- 采用
localstorage
,对页面中用户切换语言的存储。优先级高
- 读取浏览器设置的语言。
所以有如下判断:
// 浏览器设定的语言
let lang = (localStorage.getItem('currentLanguage')
|| window.navigator.language || '').includes('zh') ? 'zh' : 'en';
设置 UI 框架的多国语言
这里的 UI
框架我们以 NG-ZORRO 为例,使用的版本号为 ^12.1.1
。
现在的脚手架很聪明,我们生成项目,在添加 NG-ZORRO
的时候,它会询问我们选择哪种语言。假设默认的语言是 zh-CN
,那么你生成项目之后,在 app.module.ts
文件内,可看到下面的代码:
import { NZ_I18N } from 'ng-zorro-antd/i18n';
import { zh_CN } from 'ng-zorro-antd/i18n';
import zh from '@angular/common/locales/zh';
@NgModule({
providers: [
{ provide: NZ_I18N, useValue: zh_CN },
],
})
思路一下子就来了,我们在这里添加个条件判断,不就可以了?所以,我们更改了下:
// 引用的 ant design angular 库的语言处理
import { NZ_I18N } from 'ng-zorro-antd/i18n';
// 中文
import { zh_CN } from 'ng-zorro-antd/i18n';
import zh from '@angular/common/locales/zh';
// 英文
import { en_US } from 'ng-zorro-antd/i18n';
import en from '@angular/common/locales/en';
// 切换语言
let useLang: any = zh_CN;
switch(lang) {
case 'zh': registerLocaleData(zh); useLang = zh_CN; break;
default: registerLocaleData(en); useLang = en_US; break;
}
@NgModule(
providers: [
{ provide: NZ_I18N, useValue: useLang },
],
)
切换浏览器语言验证。
NG-ZORRO
中 Empty
组件的提示成功更改为英文:
设置自定义多国语言
那么,对于我们自定义的页面内容,怎么翻译呢?
这个有点麻烦,但是我们依然可以使用依赖库,比如 ngx-translate 实现,喜大奔普~
安装依赖
npm install @ngx-translate/core --save
npm install @ngx-translate/http-loader --save
我们项目这里的对应版本号为:
{
"@ngx-translate/core": "^14.0.0",
"@ngx-translate/http-loader": "^7.0.0",
}
在 app.module.ts
导入
// 自定义的语言处理
import { HttpClientModule } from '@angular/common/http';
import { HttpClient } from '@angular/common/http';
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
import { TranslateHttpLoader } from '@ngx-translate/http-loader';
// https://github.com/ngx-translate/core
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, 'assets/i18n/', '.json');
}
@NgModule({
imports: [
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [HttpClient]
}
})
]
});
createTranslateLoader
中我们设定了引用 i18n
多语言文件夹。这里的路径也方便我们在部署的过程中 url
的调整,比如添加个前缀 /jimmy/
。详见 Angular 项目路径添加指定的访问前缀。
添加多国语言包
我们在 assets
文件夹下面新建 i18n/*.json
。这里我们新建了 zh-CN.json
和 en-US.json
两个文件。
// zh-CN.json
{
"delete": "删除",
"generate compressed code": "生成压缩码",
"download": "下载",
"file": "文件",
}
// en-US.json
{
"delete": "Delete",
"generate compressed code": "Generate compressed code",
"download": "Download",
"file": "File",
}
app.component.ts
中初始化语言
我们在 app.component.ts
中对翻译服务初始化:
import { Component, OnInit } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
public currentLanguage: string = '';
constructor(
public translate: TranslateService
) {
}
async ngOnInit() {
let lang = (await localStorage.getItem('currentLanguage') || this.translate.getBrowserCultureLang() || '').includes('zh') ? 'zh' : 'en';
switch(lang) {
case 'zh': this.currentLanguage = 'zh-CN'; break;
default: this.currentLanguage = 'en-US'; break;
}
this.translate.setDefaultLang('en-US'); // 默认英文
this.translate.use(this.currentLanguage); // 使用当前语言
}
}
我们先判断是否存在本地存储的语言信息,如果不存在则获取浏览器设定的当前语言;当 assets/i18n/
文件夹下面没有我们要找的语言包的时候,则使用默认 en-US.json
语言包,当存在的时候,则使用选中的语言包。
使用多国语言
我们在 html
中可通过下面这样使用:
<div style="display: flex; justify-content: flex-start; flex-wrap: wrap; align-items: center;">
<button nz-button nzType="primary" (click)="encode()" [disabled]="list.length === 0" class="btn">{{ 'generate compressed code' | translate }}</button>
<button nz-button nzType="primary" (click)="downloadExl()" class="btn" [disabled]="encodeArr.length === 0">{{ 'download' | translate }} Xlsx {{ 'file' | translate }}</button>
<button nz-button nzType="primary" nzDanger (click)="emptyEncodeList()" class="btn" [disabled]="encodeArr.length === 0">{{ 'delete' | translate }}<span nz-icon nzType="delete"></span></button>
</div>
<nz-empty style="margin-top: 48px;"></nz-empty>
你可以清晰看到上面翻译的操作 {{ 'generate compressed code' | translate }}
,{{ 'download' | translate }} Xlsx {{ 'file' | translate }}
和 {{ 'delete' | translate }}
。得到的结果如下:
中文设定
英文设定
当然,如果想在页面属性中调用多语言,同理。比如在 title
属性上使用 <a href="#" [title]="'name' | translate">title</a>
。
在页面中选择
为了方便用户切换语言,我们应该在页面中设置操作。如下:
<div class="lang">
<a href="javascript: void(0)" [class]="currentLanguage.indexOf('zh') < 0 ? 'active' : 'inactive'" (click)="selectLanguage('en-US')">English</a>
<span style="display: inline-block; padding: 0 4px; color: #999;">/</span>
<a href="javascript: void(0)" [class]="currentLanguage.indexOf('zh') >= 0 ? 'active' : 'inactive'" (click)="selectLanguage('zh-CN')">中文</a>
</div>
这里的判断采用 currentLanguage.indexOf('zh')
,而不是 currentLanguage.indexOf('zh-CN')
是为了防止设定的浏览器语言是繁体中文等情况。
// 语言选择
public selectLanguage(language: string): void {
window.localStorage.setItem('currentLanguage', language);
this.translate.use(language);
this.currentLanguage = language;
}
切换语言后,我们先将其进行本地存储,再使用,当然还要切换页面的语言变量,以应用相应的样式。
Thanks for reading.