@xwink/ui

    useUiLocale

    组件库的文案出口。当前全站单语言,不引入 i18n 框架,但按可国际化的结构预留:组件模板与逻辑里 不写面向用户的字面量,要么来自 props / slots,要么来自这里。

    ts
    import { useUiLocale } from '@xwink/ui'
    
    const messages = useUiLocale()
    const m = computed(() => messages.value.profileMenu)
    

    包里带两套文案:zhCN(缺省)与 en,都是 UiMessages 类型;百分比这类格式化按各包自己的语言。取值走 computed,因为宿主 provide 的可以是响应式的。

    整套替换

    ts
    import { provideUiLocale, zhCN } from '@xwink/ui'
    
    // app 级 provide:传 ref / getter 都可以,将来接真 i18n 时换成翻译结果即可,组件零改动
    provideUiLocale(() => ({ ...zhCN, profileMenu: { ...zhCN.profileMenu, logout: '退出' } }))
    

    没有 provide 时组件回落 zhCN,所以宿主不接也能正常渲染。

    按语言切换

    双语宿主按当前语言 provide 对应的包,传 getter,切语言时组件跟着换:

    ts
    import { en, provideUiLocale, zhCN } from '@xwink/ui'
    
    provideUiLocale(() => (locale.value === 'en' ? en : zhCN))
    

    组件库新增文案键时两个包一起补,UiMessages 类型保证缺键编译不过。

    为什么不直接内联文案

    内联的字面量散在几十个 SFC 里,接 i18n 那天要逐个改;而集中在一处的代价只是多一次 computed。 日期与数字同理:用 Intl API 并从 locale 取地区参数,不手写格式化字符串。