如何包装Svelte可读Store实现带相对键的svelte-i18n调用并保留$语法?
封装svelte-i18n支持相对翻译键并保留$语法
问题描述
我是Svelte新手,想要封装svelte-i18n以支持相对翻译键。原库使用方式为导入_后通过{$_('absolute_key')}调用;期望实现导入tr函数,传入基础路径base.path.relative后生成_,通过{$_('.relative_key')}调用。当前实现的wrapper可运行,但需省略$符号,请问如何保留$语法,如同使用原生API一样?
原库使用示例
<script> import { _ } from 'svelte-i18n'; </script> <p>{$_('absolute_key')}</p>
期望使用方式
<script> import { tr } from "my_wrapper.js" const _ = tr("base.path.relative"); </script> <p>{$_('.relative_key')}</p>
当前wrapper代码
// my_wrapper.js import { _ } from 'svelte-i18n'; export const tr = (basePath) => (path, options = {}) => { let returnVal; if (path.startsWith(".")) { _.subscribe((t) => returnVal = t(`${basePath}${path}`, options)); } else { _.subscribe((t) => returnVal = t(path, options)); } return returnVal; }
解决方案
要保留$语法,关键是让tr返回的_成为Svelte可订阅的Store——原生svelte-i18n的_本身就是一个Derived Store,我们需要基于它创建自定义Derived Store来实现相对路径逻辑。
修改后的wrapper代码
// my_wrapper.js import { derived } from 'svelte/store'; import { _ } from 'svelte-i18n'; export const tr = (basePath) => { // 返回一个Derived Store,其值为带相对路径处理的翻译函数 return derived(_, (translate) => { return (path, options = {}) => { const fullPath = path.startsWith('.') ? `${basePath}${path}` : path; return translate(fullPath, options); }; }); };
组件中使用
<script> import { tr } from "my_wrapper.js"; const _ = tr("base.path.relative"); </script> <p>{$_('.relative_key')}</p>
原理说明
- 原生
svelte-i18n的_是一个Derived Store,它的值是当前语言环境对应的翻译函数,$_本质是订阅这个Store并调用其返回的翻译函数。 - 我们的
tr函数返回的同样是Derived Store,依赖于原生_Store。当原生翻译函数更新(比如切换语言),自定义Store会自动同步更新。 - 这种实现下,
_依然是Store,因此可以继续使用$_语法来订阅并调用翻译函数,完全贴合原生API的使用习惯。
内容的提问来源于stack exchange,提问作者James St-Pierre
相关产品推荐
相关产品推荐

