# i18n

本頁說明如何定義語系、在文字與屬性中引用翻譯，以及切換語言。

## 定義語系

```html
<div id="app">
  <h1>{{ i18n.title }}</h1>
  <input placeholder="i18n.search" />
  <button @click="toEn">English</button>
</div>

<script>
  const app = new QUI({
    id: "app",
    i18n: {
      zh: { title: "歡迎", search: "搜尋" },
      en: "/i18n/en.json",
    },
    i18nLang: "zh",
    event: {
      toEn: () => app.lang("en"),
    },
  });
</script>
```

| 選項 | 說明 |
|---|---|
| `i18n` | 語系代碼對應到物件，或對應到 JSON 檔的 URL |
| `i18nLang` | 初始語系，預設 `"zh"` |

字串值會在初始渲染前以 `fetch` 載入；載入失敗或回應非 2xx 時該語系視為空物件，不會中斷渲染。

## 引用翻譯

| 位置 | 寫法 | key 規則 | 找不到時 |
|---|---|---|---|
| 文字 | `{{ i18n.menu.home }}` | 支援以 `.` 存取巢狀 key | 顯示 key 本身（`menu.home`） |
| 屬性值 | `placeholder="i18n.search"` | 只支援單層 key | 保留原字串 `i18n.search` |

屬性值必須整個是 `i18n.key`，不能混入其他文字。

## 切換語言

`app.lang(code)` 會更新目前語系並觸發重新渲染；`code` 不在 `i18n` 中時不做任何事。`once: true` 的實例資料不具響應性，切換後不會重新渲染。

## 保留鍵

語系資料存放在 `app.data.quickui_i18n`，目前語系存放在 `app.data.quickui_i18nLang`。不要在自己的 `data` 中使用這兩個名稱。
