多语言
This content is not available in your language yet.
本框架采用运行时 i18n:构建期不做 xliff 抽取,也不做 AOT 内联。模板中的 i18n
和 ICU 由全局 $localize 在运行时查询译文表。
因此构建选项中没有 localize,也无需按语言分别构建产物——一份产物 + 一份译文表。
// angular.json -> options{ "polyfills": ["@angular/localize/init"] }/init 必须写全。 主入口不会自动挂载全局 $localize,只写 @angular/localize 时构建
可以通过,但运行时会抛 Cannot set properties of undefined (setting 'translate')。
{ "compilerOptions": { "types": ["@angular/localize/init"] } }否则在 TS 中使用 $localize 缺少类型声明。
2. 译文表
Section titled “2. 译文表”消息应统一用 i18n="@@xxx" 显式命名,译文表的 key 就是 xxx。若不命名,编译器会
按文案计算哈希,文案改动一个字符 id 就会变化,无法维护。
import { clearTranslations, loadTranslations } from '@angular/localize';
const EN: Record<string, string> = { 'i18n.title': 'Internationalization', 'i18n.cartCount': '{$INTERPOLATION} item(s) in the cart', 'i18n.select': '{VAR_SELECT, select, male {he} female {she} other {they}}', 'i18n.plural': '{VAR_PLURAL, plural, =0 {nothing yet} one {just one} other {{INTERPOLATION} in total}}',};
export function applyLocale(id: 'zh' | 'en') { clearTranslations(); // loadTranslations 只加不减,切回去必须先清 loadTranslations(id === 'en' ? EN : {});}loadTranslations(translations) 只接受一个参数,不存在第二个 locale 参数,
多传会被静默忽略。
译文中的占位符名必须与编译产物逐字一致,书写错误不会报错,只会静默退回源文案。
| 源写法 | 占位符 |
|---|---|
{{ a }} 单个插值 |
{$INTERPOLATION} |
| 多个插值 | {$INTERPOLATION_1} {$INTERPOLATION_2} … |
ICU select 的变量 |
{VAR_SELECT, select, …}(裸写,不带 $) |
ICU plural 的变量 |
{VAR_PLURAL, plural, …} |
| ICU 分支中的插值 | {INTERPOLATION} |
ICU 相关的几条由 ɵɵi18nPostprocess 在译文求值之后再替换,因此形态与插值不同。
占位符名称不应凭猜测,建议在产物中 grep 确认:
grep -o '`:[^`]*`' dist/<app>/pages/i18n/i18n-entry.js3. 生效时机
Section titled “3. 生效时机”模板文案的译文在组件 consts 首次求值时即已确定,而 consts 每个组件类型只求值一次。
因此译文必须在该组件首次渲染之前就位。
// main.ts —— bootstrap 之前applyLocale(readStoredLocale());bootstrapApplication();运行过程中切换语言只对尚未渲染的组件生效,已渲染的组件需要重启小程序才会更新。
在取值时求值的内容不受影响,比如在 TS 中直接调用 $localize:
get liveLabel() { return $localize`:@@i18n.live:这一行每次取值都重新求值`;}$localize 必须作为模板标签使用($localize`…`)。作为普通函数调用时无法获取
.raw,内部会抛出错误。
4. 模板中支持的写法
Section titled “4. 模板中支持的写法”| 写法 | 支持 |
|---|---|
i18n="@@id" 静态文案 |
✅ |
i18n="@@id" + {{插值}} |
✅ |
ICU { x, select, … } / { x, plural, … } |
✅ |
i18n-alt / i18n-title / i18n-aria-label 等属性 |
✅(带插值的走 setProperty,静态的走 setAttribute) |
TS 中 $localize`:@@id:文案` |
✅ |
ICU 有两条排版限制:ICU 前后的空白会被并入消息本体,因此包含 ICU 的那一行不能折行; 分支中也不能放标签。
<!-- 这样 --><p i18n="@@i18n.plural"> {count(), plural, =0 {还没有商品} one {只有一件} other {{{count()}} 件}}</p>5. 语言的持久化
Section titled “5. 语言的持久化”小程序没有 localStorage,用 wx.setStorageSync(或 MpApiService.setStorageSync):
export function readStoredLocale(): LocaleId { return wx.getStorageSync('demo.locale') === 'en' ? 'en' : 'zh';}也可以在 onLaunch 中读取小程序的 language 作为默认值。