国际化
日期与时间组件(DatePicker、DateInput、TimePicker、TimeInput)的文案、数字日期顺序与默认时钟格式 来自组件库的国际化模块。语言是模块级单例,和 useTheme() 一样:切换后所有组件立即重新渲染。
月份、星期名与日期格式化全部交给浏览器的 Intl,组件库只维护少量界面文案,因此自定义语言不用手抄月名表。
内置语言
| 代码 | 日期顺序 | 时钟格式 |
|---|---|---|
en | MM/DD/YYYY | 12 小时制 |
zh-Hans | YYYY/MM/DD | 24 小时制 |
zh-Hant | YYYY/MM/DD | 24 小时制 |
ja | YYYY/MM/DD | 24 小时制 |
默认语言是 en。组件库不会自动读取浏览器语言,也不会持久化选择——这两件事由应用决定, 例如在挂载前根据 matchLocale 设置,并把结果存进 localStorage。
文档站是中文站点,因此在 docs/.vitepress/theme/index.ts 里调用 setLocale("zh-Hans"),演示中的月份、 日期顺序与操作按钮都按简体中文显示。
切换语言
ts
import { setLocale, useI18n } from "@sharpdotnut/dotsharp";
setLocale("ja"); // true;未注册的代码会被忽略并给出警告
const { locale, t } = useI18n();
console.log(locale.value); // "ja"
console.log(t("cancel")); // "キャンセル"useI18n() 返回:
| 成员 | 类型 | 说明 |
|---|---|---|
locale | Readonly<Ref<string>> | 当前语言代码 |
intlLocale | ComputedRef<string> | 交给 Intl 的合法标签 |
order | ComputedRef<"mdy" | "dmy" | "ymd"> | 数字日期顺序 |
firstDayOfWeek | ComputedRef<1…7> | 一周首日,1 = 周一,7 = 周日 |
timeFormat | ComputedRef<"12h" | "24h"> | 默认时钟格式 |
setLocale | (code: string) => boolean | 切换语言 |
registerLocale | (code, messages, options?) => void | 注册或覆盖语言 |
t | (key: keyof LocaleMessages) => string | 当前语言的文案 |
matchLocale | (supported, requested?) => string | undefined | 从候选里挑最合适的语言 |
setLocale、registerLocale、matchLocale 也从包入口直接导出。
获取当前语言
matchLocale 用 Intl 规范化并补全语言标签(zh-TW 补全为 zh-Hant-TW),再按 完整匹配 → 同语言同书写系统 → 同语言同地区 → 同语言唯一候选 的顺序选出结果:
ts
import { matchLocale } from "@sharpdotnut/dotsharp";
const supported = ["en", "zh-Hans", "zh-Hant", "ja"];
matchLocale(supported, ["zh-TW"]); // "zh-Hant"
matchLocale(supported, ["zh-CN"]); // "zh-Hans"
matchLocale(supported, ["ja-JP"]); // "ja"
matchLocale(supported, ["fr-FR"]); // undefined省略第二个参数时读取 navigator.languages(服务端没有 navigator,返回 undefined):
ts
const locale = matchLocale(supported) ?? "en";
setLocale(locale);加载自定义语言
registerLocale 只覆盖提供的字段,其余回退到英文;order 与 firstDayOfWeek 是可选的语言级设置。 语言代码应当是合法的 BCP 47 标签,月份与星期名由它决定:
ts
import { registerLocale, setLocale } from "@sharpdotnut/dotsharp";
registerLocale(
"fr",
{
date: "Date",
enterDate: "Saisir une date",
selectDate: "Choisir une date",
invalidDate: "Date invalide",
cancel: "Annuler",
ok: "Valider",
previousMonth: "Mois précédent",
nextMonth: "Mois suivant",
time: "Heure",
selectTime: "Choisir une heure",
invalidTime: "Heure invalide",
hour: "Heure",
minute: "Minute",
second: "Seconde",
am: "AM",
pm: "PM",
clock: "Ouvrir l'horloge",
chooseMonth: "Choisir le mois",
chooseYear: "Choisir l'année",
calendar: "Ouvrir le calendrier",
},
{ order: "dmy", firstDayOfWeek: 1, timeFormat: "24h" },
);
setLocale("fr");也可以覆盖内置语言的部分字段:
ts
registerLocale("ja", { ok: "決定" });firstDayOfWeek 省略时从 Intl.Locale 的区域周信息读取,读不到则回退到周日; timeFormat 省略时也按该语言的区域小时制推断(h11 / h12 为 12 小时制,其余为 24 小时制)。
服务端渲染
语言状态在模块作用域里,服务端与浏览器各有一份。为了让 SSR 输出与首次水合一致:
- 服务端与浏览器都用同一个初始语言(默认
en),或把语言放在应用的根上下文里统一设置; - 依赖
navigator/localStorage的自动检测放到onMounted,不要让首次渲染读到浏览器状态; - 文档站里所有触碰浏览器状态的示例都用
mountedref 包一层。
新增文案
组件的界面文案集中在 src/i18n/index.ts 的 LocaleMessages;新增日期组件文案时先加英文键, 再补三种内置翻译,t 的键类型会自动覆盖到自定义语言。