ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Vant 国际化完全指南:多语言切换、语言包定制与 Locale 源码原理

Vant 国际化完全指南:多语言切换、语言包定制与 Locale 源码原理 Vant 国际化完全指南多语言切换、语言包定制与 Locale 源码原理【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vantVant 默认使用中文作为组件内置文案的语言同时内置了一套轻量、可扩展的国际化i18n机制。本文以官方文档为核心结合vant仓库中 Locale 模块的真实实现系统讲解如何使用Locale.use切换语言、用Locale.add覆盖或扩展语言包、如何获取当前语言并深入剖析语言包的目录结构与底层源码帮助你掌握从切换语言到自定义组件文案的完整能力。国际化机制概览Vant 的国际化能力由packages/vant/src/locale/index.ts提供对外暴露两个核心 APIAPI作用Locale.use(newLang, newMessages?)切换当前语言可同时传入该语言的文案包Locale.add(newMessages)新增或覆盖文案可修改任意语言的任意条目useCurrentLang()获取当前语言响应式Refstring默认语言为简体中文zh-CN也就是说在不做任何配置的情况下Calendar、Picker、CouponList、AddressEdit 等组件展示的内置文案均为中文。默认语言包位于 packages/vant/src/locale/lang/zh-CN.ts。多语言切换Locale.use通过Locale.use方法即可在运行时切换组件内置文案的语言import { Locale } from vant; // 引入英文语言包 import enUS from vant/es/locale/lang/en-US; Locale.use(en-US, enUS);其中vant/es/locale/lang/en-US指向编译产物中的英文语言包en-US是语言的标识 key与语言包文件名保持一致。切换后所有基于 Locale 读取文案的组件会立刻使用新语言的文案。源码实现查看 packages/vant/src/locale/index.ts 可以看到use的实现非常简洁const lang ref(zh-CN); const messages reactiveMessages({ zh-CN: defaultMessages, }); export const Locale { use(newLang: string, newMessages?: Message) { lang.value newLang; this.add({ [newLang]: newMessages }); }, add(newMessages: Message {}) { deepAssign(messages, newMessages); }, };lang是一个 Vueref初始值为zh-CN所以useCurrentLang()在未切换时返回zh-CNuse内部会先更新lang.value再调用add把新语言包合并进messages响应式对象messages是reactive对象所有组件的文案都从中读取因此切换语言后组件文案会响应式地更新。值得注意的是Locale.use(en-US, enUS)的第二个参数是可选的如果之前已经通过Locale.add合并过en-US的文案可以只传语言 key。从实现看若省略newMessagesadd({ en-US: undefined })会被deepAssign安全忽略undefined值不会被写入不会破坏已有文案。覆盖与扩展语言包Locale.add当默认语言包中的文案不符合业务需求时例如把 Picker 的确认按钮改为关闭可以使用Locale.add覆盖指定条目import { Locale } from vant; const messages { zh-CN: { vanPicker: { confirm: 关闭, // 将确认修改为关闭 }, }, }; Locale.add(messages);Locale.add的用途不止于覆盖它可以新增一种全新的语言、为某个组件补充新文案字段、或是整体替换某个语言包。传入的对象结构为语言key - 组件key - 文案字段与语言包文件的内部结构一一对应。deepAssign合并的底层逻辑add依赖的工具函数是packages/vant/src/utils/deep-assign.ts中的deepAssign。它会递归遍历传入对象的每个 key 并合并进目标对象合并规则如下function assignKey(to, from, key) { const val from[key]; if (!isDef(val)) { return; // 值为 null / undefined 时跳过不覆盖 } if (!hasOwnProperty.call(to, key) || !isObject(val)) { to[key] val; // 目标无此 key 或值为非对象时直接赋值 } else { to[key] deepAssign(Object(to[key]), val); // 双方都是对象时递归合并 } }这意味着部分覆盖只需传入要修改的那一层路径其余文案保持原样例如上面示例只改了vanPicker.confirmvanPicker的其他字段不受影响跳过空值null或undefined的值不会被写入避免误清空已有文案深度合并对象类型逐层递归合并适合新增多级嵌套的语言配置。语言包清单当前支持的 39 种语言Vant 内置了 39 种语言的完整语言包源文件全部位于 packages/vant/src/locale/lang 目录每个语言一个*.ts文件。下表列出官方文档声明的全部语言及对应的文件名、引入版本语言文件名版本阿拉伯语ar-SAv3.5.0保加利亚语bg-BGv3.5.0孟加拉语孟加拉国bn-BDv3.4.5丹麦语da-DKv3.4.8德语de-DE-德语正式de-DE-formal-希腊语el-GRv3.5.0英语en-US-世界语eo-EOv4.0.9西班牙语西班牙es-ES-波斯语fa-IRv3.5.0法语fr-FR-希伯来语he-ILv3.5.0印地语hi-INv3.4.3印度尼西亚语id-IDv3.4.5冰岛语is-ISv3.4.7意大利语it-ITv3.4.5日语ja-JP-哈萨克语kk-KZ-高棉语km-KHv4.1.2韩语/朝鲜语ko-KRv3.4.3老挝语la-LAv3.4.7蒙古语mm-MNv4.0.5挪威语nb-NO-挪威尼诺斯克语nn-NO-荷兰语nl-NLv4.0.5波兰语pl-PLv4.9.17葡萄牙语巴西pt-BRv3.3.3罗马尼亚语ro-RO-俄语ru-RUv3.1.5塞尔维亚语sr-RSv4.6.4瑞典语sv-SEv3.4.7泰语th-TH-土耳其语tr-TR-乌克兰语uk-UAv3.4.5越南语vi-VNv3.4.5简体中文zh-CN-繁体中文港zh-HK-繁体中文台zh-TW-表格中版本一列表示该语言包在对应 Vant 版本中引入标注-的语言随组件库首个稳定版本一同提供。切换语言时导入路径统一为vant/es/locale/lang/文件名ESM 产物或vant/lib/locale/lang/文件名CommonJS 产物例如日语包import jaJP from vant/es/locale/lang/ja-JP。语言包内部结构通用文案与组件文案以默认语言包 zh-CN.ts 为例一个语言包的结构分为两层顶层通用字段如name姓名、tel电话、confirm确认、loading加载中...等供多个组件共享的基础文案组件级字段以vanXxx命名空间组织如vanCalendar、vanCascader、vanPagination、vanPullRefresh、vanSubmitBar、vanCoupon、vanCouponCell、vanCouponList、vanAddressEdit、vanAddressList。字段值既可以是普通字符串也可以是接收参数的函数用于动态生成文案。例如 en-US.ts 中的vanCalendar: { monthTitle: (year: number, month: number) ${year}/${month}, rangePrompt: (maxRange: number) Choose no more than ${maxRange} days, }, vanCoupon: { discount: (discount: number) ${discount * 10}% off, },对应中文包 zh-CN.ts 中则为monthTitle: (year, month) ${year}年${month}月、discount: (discount) ${discount}折。这类函数式文案在Locale.add覆盖时同样支持——直接传入同签名函数即可。繁体中文的两个变体zh-HK.ts、zh-TW.ts整体结构与简体版保持一致仅在用字和措辞上存在差异如保存/儲存/儲存、確認/確認/確認可以直观对照出语言包的组织范式。组件如何读取文案createTranslate组件侧读取文案的统一入口是packages/vant/src/utils/create.ts中的createTranslateexport function createTranslate(name: string) { const prefix camelize(name) .; return (path: string, ...args: unknown[]) { const messages locale.messages(); const message get(messages, prefix path) || get(messages, path); return isFunction(message) ? message(...args) : message; }; }createNamespace会为每个组件生成t翻译函数组件内调用t(confirm)时实际查找路径为vanPicker.confirm组件名前缀 字段名如果带前缀的路径找不到还会回退到顶层通用字段如t(confirm)直接命中顶层confirm。这解释了为什么语言包中同时存在顶层通用文案和组件级文案它们分别服务于多组件共享与组件专属两类场景。函数式文案在读取时会自动传入组件调用时的参数。获取当前语言useCurrentLang组件或业务代码中可以使用useCurrentLang获取当前语言import { useCurrentLang } from vant; const currentLang useCurrentLang(); console.log(currentLang.value); // -- zh-CN切换语言后自动更新其类型签名为function useCurrentLang(): Refstring;从源码看它返回的就是index.ts内部的lang响应式引用export const useCurrentLang () lang。由于它直接返回ref对象在 Vue 组件的setup中使用时具备响应式能力——调用Locale.use切换语言后依赖currentLang.value的视图逻辑会自动更新。这常用于需要根据当前语言动态渲染业务文案、或联动vue-i18n等第三方方案的场景。添加新语言如果内置的 39 种语言中没有你需要的语言可以向 Vant 提交 Pull Request 来新增语言包。参考做法在 packages/vant/src/locale/lang 目录下新建xx-XX.ts文件结构完全参照zh-CN.ts或en-US.ts保持顶层通用字段与所有vanXxx组件命名空间齐全在packages/vant/src/locale/index.ts中如需默认注册以及文档语言列表中登记新语言提交 PR由维护者合并后随版本发布。历史上德语、蒙古语等语言包均通过社区 PR 加入。社区新增语言包时需确保字段完整性因为语言包会被所有组件读取缺失字段会导致对应组件文案回退或显示空白。若只是临时使用也可以不提交 PR直接通过Locale.add在业务侧注入自定义语言包。常见问题找不到所需的语言包如果上方列表中没有你需要的语言欢迎向 Vant 提交 Pull Request 新增语言包改动范围以语言包目录 packages/vant/src/locale/lang 为主内容可参考语言包组织范式进行翻译与补充。业务代码如何实现国际化Vant 的 Locale 只负责组件内置文案的国际化。业务代码自身的文案如页面标题、业务表单提示语不属于组件库职责范围官方推荐使用社区成熟的国际化方案vue-i18n来实现。通常的做法是用useCurrentLang()监听 Vant 当前语言并在切换时同步调用vue-i18n的locale切换使组件文案与业务文案保持同一语言。以 CDN 形式引入时如何使用语言包目前 Vant 没有提供 CDN 形式的语言包文件。若通过 CDN 的script标签方式使用 Vant可以手动将 packages/vant/src/locale/lang 中对应语言的源码内容拷贝到业务代码中再通过Locale.add或Locale.use注入使用效果与打包引入一致。语言包中不包含 Sku 组件语言包中默认不包含 Sku 业务组件的语言配置。Sku 属于业务属性较强的组件官方语言包未为其提供内置文案因此如有 Sku 组件的国际化需求需要结合自身业务通过Locale.add自行配置对应文案或直接在业务代码中做多语言处理。小结Vant 的国际化体系以packages/vant/src/locale/index.ts的 Locale 对象为核心Locale.use负责运行时切换语言Locale.add借助deepAssign实现深度合并的文案覆盖与扩展useCurrentLang提供响应式的当前语言读取39 种内置语言包按顶层通用字段 vanXxx组件命名空间的固定结构组织在 packages/vant/src/locale/lang 目录下配合createTranslate的前缀查找与函数式文案能力构成了一个轻量、可扩展、与组件渲染深度集成的完整多语言方案。无论是开箱即用的语言切换还是面向业务的文案定制这套机制都足够覆盖移动端应用的典型国际化需求。【免费下载链接】vantA lightweight, customizable Vue UI library for mobile web apps.项目地址: https://gitcode.com/GitHub_Trending/va/vant创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表