format — message interpolation
Total {total} items, {n} stars, Step {index} — message templates in the language packs need their placeholders replaced with runtime numbers. This interpolation capability used to live inside the locales singleton, but when core components used it (rate’s star count, pagination’s page count), it made core reverse-depend on the module-level singleton side effects of locales. After being distilled into a pure string function, the message interpolation of core components depends on no singleton at all.
Import
Section titled “Import”// From the shared kernel (recommended)import { formatMessage } from '@lh-ui/share/core/shared/format'
// Or from the locales entry point (the export surface is unchanged)import { formatMessage } from '@lh-ui/share/locales'Function table
Section titled “Function table”| Function | Signature | Purpose |
|---|---|---|
formatMessage |
(template: string, params?: Record<string, unknown>) => string |
Replaces '{key}' placeholders with values from params |
Behavioral details
Section titled “Behavioral details”formatMessage('Total {total} items', { total: 42 }) // 'Total 42 items'formatMessage('{n} stars', { n: 5 }) // '5 stars'formatMessage('No placeholder') // 'No placeholder'formatMessage('Unknown placeholder {missing}') // 'Unknown placeholder {missing}'Three rules:
- Unknown placeholders are kept as-is. No error, no replacement with an empty string — the caller has usually already fetched a template with placeholders from the language pack, so a placeholder without a matching parameter means the upstream forgot to pass it; keeping it makes the problem visible in the UI (instead of silently swallowing it).
- Values are uniformly
String(...): numbers and booleans can both be interpolated. paramsdefaults to{}: with no parameters, the template passes through unchanged.
Relationship with lhlocale
Section titled “Relationship with lhlocale”lhlocale.t(path, params) internally is “look up the language pack → get the template → call formatMessage”:
// simplified internals of localest(path, fallbackOrParams) { const template = resolve(path) ?? fallback return typeof fallbackOrParams === 'object' ? formatMessage(template, fallbackOrParams) : template}@lh-ui/share/locales re-exporting formatMessage is deliberate — it was on the old export surface, and after the function moved down into core, the import path stayed the same so downstream code needed zero changes.
When to use it and when not to
Section titled “When to use it and when not to”| Scenario | Use it? |
|---|---|
| Message interpolation inside a core component | ✅ Use formatMessage directly (no locales singleton imported) |
| Message interpolation in application code | ✅ Safer than str.replace (unknown placeholders are kept) |
| Need a language-pack lookup plus interpolation | ❌ Use lhlocale.t(path, params) — one step |
| Templates need conditionals / plurals | ❌ This function only does naive replacement; conditional copy should be split into multiple keys in the language pack |
Usage examples
Section titled “Usage examples”pagination’s total-count text
Section titled “pagination’s total-count text”// inside the componentconst totalText = computed(() => formatMessage(lhlocale.t('pagination.total'), { total: props.total }),)// language pack: 'Total {total} items' → 'Total 42 items'rate’s star-count announcement
Section titled “rate’s star-count announcement”const ariaLabel = formatMessage(lhlocale.t('rate.stars'), { n: currentValue.value })// language pack: '{n} stars' → '3 stars'A general string utility
Section titled “A general string utility”// pure interpolation with no language pack involvedformatMessage('Step {index} of {total}', { index: 2, total: 5 })// 'Step 2 of 5'Caveats
Section titled “Caveats”- The placeholder syntax is
{key}(single braces), not${key}and not{{key}}. - Nested templates are not supported: the values in
paramsare run throughString()once and are not parsed recursively. - Performance: a single call does a
String.replaceloop — do not call it repeatedly on the same template inside a high-frequency loop; have the UI layer cache it in acomputed.
@lh-ui/share/core/format → formatMessage( )(填好参数后点运行)Copyright © 2024-2026 FengMo WenXue