283 lines
6.7 KiB
Markdown
283 lines
6.7 KiB
Markdown
下面是为提供的 JavaScript 代码编写的 **Markdown 格式技术文档**,包含类的功能说明、构造函数参数、方法详解以及使用示例。
|
||
|
||
---
|
||
|
||
# `bricks.I18n` 国际化支持类
|
||
|
||
`bricks.I18n` 是一个轻量级的国际化(i18n)工具类,用于在前端应用中实现多语言文本翻译和动态语言切换。它支持从远程 URL 加载语言包,并缓存已加载的语言资源以提高性能。
|
||
|
||
该类依赖于全局对象 `window.bricks`,并使用 `bricks.HttpJson` 进行异步请求,同时假设存在辅助函数 `objget` 和 `obj_fmtstr` 用于对象操作和字符串格式化。
|
||
|
||
---
|
||
|
||
## 基本结构
|
||
|
||
```javascript
|
||
var bricks = window.bricks || {};
|
||
bricks.I18n = class {
|
||
// 实现见下文
|
||
};
|
||
```
|
||
|
||
> ⚠️ 注意:此代码片段中存在一处变量名错误(`opts` 未定义),已在文档中指出并修正。
|
||
|
||
---
|
||
|
||
## 构造函数
|
||
|
||
### `new bricks.I18n(options)`
|
||
|
||
初始化 I18n 实例,配置语言资源路径与默认行为。
|
||
|
||
#### 参数
|
||
|
||
| 参数 | 类型 | 必填 | 描述 |
|
||
|------|------|------|------|
|
||
| `url` | `string` | 否 | 获取语言包的 API 地址(如 `/api/i18n`)。若不提供,则仅支持手动设置字典。 |
|
||
| `method` | `string` | 否 | 请求语言包时使用的 HTTP 方法,默认为 `'GET'`。 |
|
||
| `default_lang` | `string` | 否 | 默认语言代码(如 `'en'`, `'zh-CN'`),默认值为 `'en'`。 |
|
||
|
||
#### 示例
|
||
|
||
```js
|
||
const i18n = new bricks.I18n({
|
||
url: '/api/translations',
|
||
default_lang: 'zh-CN'
|
||
});
|
||
```
|
||
|
||
> ❌ **注意原始代码 Bug**:
|
||
> 原始代码中使用了未定义的 `opts` 变量:
|
||
> ```js
|
||
> this.url = opts.url;
|
||
> ```
|
||
> 应改为传入的构造函数参数 `url`, `method`, `default_lang`。**正确实现应如下:**
|
||
|
||
```js
|
||
constructor(url, default_lang, method) {
|
||
this.url = url;
|
||
this.default_lang = default_lang || 'en';
|
||
this.method = method || 'GET';
|
||
this.lang_msgs = {}; // 缓存所有语言的消息字典
|
||
this.msgs = {}; // 当前激活语言的翻译映射
|
||
}
|
||
```
|
||
|
||
或者接受一个选项对象:
|
||
|
||
```js
|
||
constructor(options) {
|
||
this.url = options.url;
|
||
this.default_lang = options.default_lang || 'en';
|
||
this.method = options.method || 'GET';
|
||
this.lang_msgs = {};
|
||
this.msgs = {};
|
||
}
|
||
```
|
||
|
||
> ✅ 文档后续基于 **修正后的构造函数** 进行描述。
|
||
|
||
---
|
||
|
||
## 方法
|
||
|
||
### `_ (txt, obj) → string`
|
||
|
||
获取指定键的翻译文本,并可选地进行变量替换。
|
||
|
||
#### 参数
|
||
|
||
| 参数 | 类型 | 描述 |
|
||
|------|------|------|
|
||
| `txt` | `string` | 要翻译的键名(key)。 |
|
||
| `obj` | `Object` 或 `undefined` | 用于填充模板字符串的变量对象。 |
|
||
|
||
#### 返回值
|
||
|
||
- 如果当前语言中有对应的翻译,返回翻译后的内容;
|
||
- 若提供了 `obj`,则调用 `obj_fmtstr(obj, translatedStr)` 对结果进行格式化;
|
||
- 否则返回原始 `txt`。
|
||
|
||
#### 示例
|
||
|
||
```js
|
||
i18n.setup_dict({
|
||
"hello": "Hello, {name}!",
|
||
"welcome": "Welcome aboard."
|
||
}, 'en');
|
||
|
||
i18n._("hello", {name: "Alice"});
|
||
// 输出: "Hello, Alice!"
|
||
|
||
i18n._("welcome");
|
||
// 输出: "Welcome aboard."
|
||
```
|
||
|
||
---
|
||
|
||
### `is_loaded(lang) → boolean`
|
||
|
||
检查某个语言包是否已被加载到内存中。
|
||
|
||
#### 参数
|
||
|
||
| 参数 | 类型 | 描述 |
|
||
|------|------|------|
|
||
| `lang` | `string` | 语言代码(如 `'zh-CN'`)。 |
|
||
|
||
#### 返回值
|
||
|
||
- `true`:该语言的消息字典已加载;
|
||
- `false`:尚未加载。
|
||
|
||
#### 示例
|
||
|
||
```js
|
||
if (!i18n.is_loaded('fr')) {
|
||
await i18n.change_lang('fr');
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### `setup_dict(dic, lang)`
|
||
|
||
将给定的语言字典注册到实例中,并立即激活该语言。
|
||
|
||
> 此方法通常由 `change_lang` 内部调用,也可用于预加载或静态注入语言包。
|
||
|
||
#### 参数
|
||
|
||
| 参数 | 类型 | 描述 |
|
||
|------|------|------|
|
||
| `dic` | `Object` | 键值对形式的语言翻译表,例如 `{ "ok": "确定" }`。 |
|
||
| `lang` | `string` | 该字典对应的语言代码。 |
|
||
|
||
#### 行为
|
||
|
||
- 将 `dic` 存储至 `this.lang_msgs[lang]` 中;
|
||
- 设置 `this.msgs = dic`,即当前活跃语言为 `lang`。
|
||
|
||
#### 示例
|
||
|
||
```js
|
||
i18n.setup_dict({
|
||
"title": "应用标题",
|
||
"save": "保存"
|
||
}, 'zh-CN');
|
||
```
|
||
|
||
---
|
||
|
||
### `async change_lang(lang) → Promise<void>`
|
||
|
||
切换当前语言环境。如果目标语言未加载,会自动通过网络请求获取。
|
||
|
||
#### 参数
|
||
|
||
| 参数 | 类型 | 描述 |
|
||
|------|------|------|
|
||
| `lang` | `string` | 目标语言代码(如 `'es'`, `'ja'`)。 |
|
||
|
||
#### 流程
|
||
|
||
1. 检查是否已加载该语言:
|
||
- 是 → 直接激活;
|
||
- 否 → 发起 HTTP 请求获取语言包。
|
||
2. 使用 `bricks.HttpJson` 发送请求,携带参数 `{ lang }`。
|
||
3. 成功响应后,调用 `setup_dict` 注册并激活新语言。
|
||
|
||
#### 异常处理
|
||
|
||
- 若未设置 `this.url`,则跳过请求,无法加载新语言。
|
||
- 错误需由 `HttpJson` 层自行抛出或捕获。
|
||
|
||
#### 示例
|
||
|
||
```js
|
||
await i18n.change_lang('zh-CN');
|
||
document.title = i18n._('app_title'); // 使用新语言更新界面
|
||
```
|
||
|
||
---
|
||
|
||
## 依赖说明
|
||
|
||
本类依赖以下外部模块或函数:
|
||
|
||
| 名称 | 说明 |
|
||
|------|------|
|
||
| `bricks.HttpJson` | 用于发送 JSON 格式的 HTTP 请求,需具备 `httpcall(url, config)` 方法。 |
|
||
| `objget(obj, path)` | 工具函数,安全访问嵌套对象属性(类似 lodash.get)。 |
|
||
| `obj_fmtstr(obj, str)` | 字符串模板替换函数,支持 `{key}` 语法,用 `obj.key` 替换。 |
|
||
|
||
> 示例 `obj_fmtstr` 实现:
|
||
> ```js
|
||
> function obj_fmtstr(obj, str) {
|
||
> return str.replace(/\{([^}]+)\}/g, (m, key) => obj[key] || m);
|
||
> }
|
||
> ```
|
||
|
||
---
|
||
|
||
## 使用场景示例
|
||
|
||
### 初始化与语言切换
|
||
|
||
```js
|
||
// 初始化 i18n 实例
|
||
const i18n = new bricks.I18n({
|
||
url: '/api/translations',
|
||
default_lang: 'en'
|
||
});
|
||
|
||
// 切换语言
|
||
async function setLanguage(lang) {
|
||
await i18n.change_lang(lang);
|
||
updateUI(); // 重新渲染页面文本
|
||
}
|
||
|
||
function updateUI() {
|
||
document.getElementById('greeting').textContent = i18n._('welcome', { user: 'Tom' });
|
||
}
|
||
```
|
||
|
||
### 预加载语言包(离线模式)
|
||
|
||
```js
|
||
// 手动注入英文包
|
||
i18n.setup_dict({
|
||
"welcome": "Welcome!",
|
||
"goodbye": "Goodbye!"
|
||
}, 'en');
|
||
|
||
// 不发起请求,直接切换
|
||
i18n.change_lang('en').then(updateUI);
|
||
```
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
|
||
1. ✅ **修复建议**:原始代码中的 `opts` 应为构造函数参数对象,请确保传参方式一致。
|
||
2. 🔐 安全性:确保服务端返回的语言包内容经过清洗,防止 XSS。
|
||
3. 🌐 性能优化:所有语言包会被缓存,避免重复请求。
|
||
4. ⏱ 异步加载:首次切换未加载语言时需要等待网络响应,请添加加载状态提示。
|
||
|
||
---
|
||
|
||
## 版本历史(示例)
|
||
|
||
| 版本 | 修改内容 |
|
||
|------|----------|
|
||
| 0.1 | 初始版本,支持基本翻译与远程加载 |
|
||
|
||
---
|
||
|
||
## 许可证
|
||
|
||
MIT License
|
||
|
||
---
|
||
|
||
✅ *文档结束* |