运行时模式
在 Lit Localize 运行时模式中,会为你的每个语言环境生成一个 JavaScript 或 TypeScript 模块。每个生成的模块包含该语言环境的本地化模板。当你的应用程序切换语言环境时,会导入该语言环境的模块,并重新渲染所有本地化的组件。
查看输出模式以比较 Lit Localize 输出模式。
// locales/es-419.ts
export const templates = {
h3c44aff2d5f5ef6b: html`Hola <b>Mundo!</b>`,
};
使用运行时模式的示例
Permalink to "使用运行时模式的示例"以下示例演示了使用 Lit Localize 运行时模式构建的应用程序:
Lit GitHub 仓库包含完整的可用示例 (JavaScript, TypeScript) 的 Lit Localize 运行时模式,你可以将其用作模板。
配置运行时模式
Permalink to "配置运行时模式"在你的 lit-localize.json
配置中,将 output.mode
属性设置为 runtime
,并将 output.outputDir
属性设置为你希望生成本地化模板模块的位置。有关更多详细信息,请参阅运行时模式设置。
接下来,将 output.localeCodesModule
设置为你选择的文件路径。Lit Localize 将在此处生成一个 .js
或 .ts
模块,该模块将配置文件中的 sourceLocale
和 targetLocales
设置映射为导出的变量。生成的模块将如下所示:
export const sourceLocale = 'en';
export const targetLocales = ['es-419', 'zh-Hans'];
export const allLocales = ['en', 'es-419', 'zh-Hans'];
最后,在你的 JavaScript 或 TypeScript 项目中,调用 configureLocalization
,传递一个具有以下属性的对象:
sourceLocale: string
:由你生成的output.localeCodesModule
模块导出的sourceLocale
变量。targetLocales: string[]
:由你生成的output.localeCodesModule
模块导出的targetLocales
变量。loadLocale: (locale: string) => Promise<LocaleModule>
:加载本地化模板的函数。返回一个 promise,解析为给定语言代码的生成本地化模板模块。有关可以在此处使用的函数的示例,请参阅加载语言环境模块的方法。
configureLocalization
返回一个具有以下属性的对象:
getLocale
:返回当前活动的语言环境代码的函数。如果新的语言环境已经开始加载,getLocale
将继续返回先前的语言环境代码,直到新的语言环境加载完成。setLocale
:开始将活动语言环境切换到给定代码的函数,并返回一个 promise,该 promise 在新语言环境加载完成时解析。
例如:
import {configureLocalization} from '@lit/localize';
// 通过 output.localeCodesModule 生成
import {sourceLocale, targetLocales} from './generated/locale-codes.js';
export const {getLocale, setLocale} = configureLocalization({
sourceLocale,
targetLocales,
loadLocale: (locale) => import(`/locales/${locale}.js`),
});
自动重新渲染
Permalink to "自动重新渲染"要在每次活动语言环境切换时自动触发组件的重新渲染,当使用 JavaScript 时,在你的 constructor
中应用 updateWhenLocaleChanges
函数;当使用 TypeScript 时,将 @localized
装饰器应用于你的类。
import {LitElement, html} from 'lit';
import {customElement} from 'lit/decorators.js';
import {msg, localized} from '@lit/localize';
@customElement('my-element');
@localized()
class MyElement extends LitElement {
render() {
// 每当调用 setLocale() 且该语言环境的模板加载完成时,
// 将重新调用此 render() 函数。
return msg(html`Hello <b>World!</b>`);
}
}
import {LitElement, html} from 'lit';
import {msg, updateWhenLocaleChanges} from '@lit/localize';
class MyElement extends LitElement {
constructor() {
super();
updateWhenLocaleChanges(this);
}
render() {
// 每当调用 setLocale() 且该语言环境的模板加载完成时,
// 将重新调用此 render() 函数。
return msg(html`Hello <b>World!</b>`);
}
}
customElements.define('my-element', MyElement);
lit-localize-status
事件会在语言环境切换开始、完成或失败时在 window
上触发。你可以使用此事件来:
在无法使用
@localized
装饰器时重新渲染(例如,当直接使用 Litrender
函数时)。在语言环境切换开始时立即渲染,甚至在其加载完成之前(例如,显示加载指示器)。
执行其他与本地化相关的任务(例如,设置语言环境偏好 cookie)。
detail.status
字符串属性告诉你发生了什么类型的状态变化,可以是 loading
、ready
或 error
:
- loading
新的语言环境已开始加载。
detail
对象包含:loadingLocale: string
:开始加载的语言环境代码。
如果在第一个语言环境加载完成之前请求第二个语言环境,则会分发新的
loading
事件,并且不会为第一个请求分发ready
或error
事件。loading
状态后面可以跟随ready
、error
或loading
状态。- ready
新的语言环境已成功加载并准备好进行渲染。
detail
对象包含:readyLocale: string
:已成功加载的语言环境代码。
ready
状态后面只能跟随loading
状态。- error
新的语言环境加载失败。
detail
对象包含:errorLocale: string
:加载失败的语言环境代码。errorMessage: string
:语言环境加载失败的错误消息。
error
状态后面只能跟随loading
状态。
使用状态事件的示例
Permalink to "使用状态事件的示例"// 每当新的语言环境正在加载时显示/隐藏进度指示器,
// 并在每次新的语言环境成功加载时重新渲染应用程序。
window.addEventListener('lit-localize-status', (event) => {
const spinner = document.querySelector('#spinner');
if (event.detail.status === 'loading') {
console.log(`Loading new locale: ${event.detail.loadingLocale}`);
spinner.removeAttribute('hidden');
} else if (event.detail.status === 'ready') {
console.log(`Loaded new locale: ${event.detail.readyLocale}`);
spinner.setAttribute('hidden', '');
renderApplication();
} else if (event.detail.status === 'error') {
console.error(
`Error loading locale ${event.detail.errorLocale}: ` +
event.detail.errorMessage
);
spinner.setAttribute('hidden', '');
}
});
加载语言环境模块的方法
Permalink to "加载语言环境模块的方法"Lit Localize 让你可以按照自己喜欢的方式加载语言环境模块,因为你可以将任何函数作为 loadLocale
选项传递。以下是一些常见的模式:
使用动态导入来仅在语言环境变为活动状态时加载每个语言环境。这是一个很好的默认选择,因为它最小化了用户将下载和执行的代码量。
import {configureLocalization} from '@lit/localize';
import {sourceLocale, targetLocales} from './generated/locale-codes.js';
const {getLocale, setLocale} = configureLocalization({
sourceLocale,
targetLocales,
loadLocale: (locale) => import(`/locales/${locale}.js`),
});
在页面加载时开始预加载所有语言环境。仍然使用动态导入来确保页面上的其余脚本不会在获取语言环境模块时被阻塞。
import {configureLocalization} from '@lit/localize';
import {sourceLocale, targetLocales} from './generated/locale-codes.js';
const localizedTemplates = new Map(
targetLocales.map((locale) => [locale, import(`/locales/${locale}.js`)])
);
const {getLocale, setLocale} = configureLocalization({
sourceLocale,
targetLocales,
loadLocale: async (locale) => localizedTemplates.get(locale),
});
使用静态导入以阻塞页面上其他脚本的方式预加载所有语言环境。
这种方法通常不推荐,因为它会导致在页面上的其他脚本执行之前获取和执行更多不必要的代码,这会阻塞交互性。只有在你的应用程序极小、必须在单个 JavaScript 文件中分发,或者你有其他限制阻止使用动态导入时,才使用这种方法。
import {configureLocalization} from '@lit/localize';
import {sourceLocale, targetLocales} from './generated/locale-codes.js';
import * as templates_es_419 from './locales/es-419.js';
import * as templates_zh_hans from './locales/zh-Hans.js';
...
const localizedTemplates = new Map([
['es-419', templates_es_419],
['zh-Hans', templates_zh_hans],
...
]);
const {getLocale, setLocale} = configureLocalization({
sourceLocale,
targetLocales,
loadLocale: async (locale) => localizedTemplates.get(locale),
});