翻译变换
VoerkaI18n提供了一种翻译变换的机制,用来对翻译结果进行变换,转换为其他形式,如Vue的ref、solidjs的solid等,用于满足响应式渲染的需要。
重点
$t函数代替t函数,用来返回一个响应式的翻译结果。
使用方法
第1步:创建变换函数
在src/languages目录下创建transform.ts文件,用来存放翻译变换函数。
export transform = (scope:VoerkaI18nScope) => {
// result是t函数的返回值
return (result:string)=>{
// return <变换后的结果>
}
}第2步:启用变换函数
修改src/languages/index.{js|ts}文件,启用变换函数。
import { transform } from "./transform"
export const i18nScope = new VoerkaI18nScope({
transform, // 翻译变换
// ...
})
export const $t = i18nScope.$t提示
使用$t函数时,会先调用t函数,然后将结果传递给transform函数。$t等效于transform(t(...))。
第3步:使用$t翻译函数
在组件中的某些场景可以使用$t函数代表t函数。
重点在于哪些场景需要使用$t函数,以及如何使用$t函数。要把握以下几个原则:
- 场景:只有在需要响应式渲染的场景下使用
$t函数。 - 不同的响应式框架,使用方式不同,如
Vue的ref、solidjs的signal等。 - 一般情况下,
$t函数用来返回一个响应式的翻译结果,如Vue/ref、Solid/signal等。
重点
不同的响应式框架,transform的实现是不一样的。但均统一导出$t函数。
工作原理
为了更好的理解翻译变换的使用方法,我们以Vue为例,来充分了解翻译变换的工作原理和使用方法。
分析问题
首先我们来看一个简单的Vue组件:
<template>
<div>
<p>{{ title }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { i18nScope } from 'languages'
const title = ref(i18nScope.t("title"))
</script>在上面的代码中,我们使用了ref函数来创建一个响应式的title变量,然后使用t函数来翻译title。
然后,初学者可能会想到,当切换语言时, Vue会自动重新渲染title组件。
但是事实是不会的,因为虽然title是一个ref变量。但切换语言时,并没有修改ref(title)的值,也就不会触发Vue的重新渲染。因此,上面的代码并不能实现切换语言时自动重新渲染。
如何解决这个问题呢?这就需要使用$t函数来解决。
切换响应式
按上面的分析,当切换语言时并没有修改ref(title)的值,也就不会触发Vue的重新渲染。
因此,要解决此问题,我们需要在语言切换时,更新ref(title)值,才会导致Vue组件的重新渲染。
这样,解决方案就很明显了,我们响应语言切换事件。
<template>
<div>
<p>{{ title }}</p>
</div>
</template>
<script setup>
import { ref, onMount } from 'vue'
import { i18nScope } from './languages'
const title = ref(i18nScope.t("title"))
let subscriber
onMounted(()=>{
subscriber = i18nScope.on('change',()=>{
title.value = t('你好')
})
})
onUnmounted(()=>{
subscriber.off()
})
</script>说明:
- 在组件
onMounted时,订阅i18nScope的change事件。 - 在
change事件中,更新title的值,触发Vue的重新渲染。 - 在组件
onUnmounted时,取消订阅i18nScope的change事件。
重点
将响应式机制与语言切换事件结合,可以实现切换语言时自动重新渲染组件。
引入翻译变换
考虑到类似的场景会出现在很多响应式框架中,我们可以将这个逻辑抽象出来,封装成一个transform函数,来简化此应用场景。
- 不同的响应式框架只需要实现相应的
transform的实现即可。 - 由于响应式框架的工作原理和
API均不同,transform的实现是不一样,但在$t函数的使用上是一样的。