问题
常见的I18n是单纯的文案,但有时候我们也会遇到需要嵌套变量甚至点击事件的文案。 其实开发中是建议文案和需要的操作文案单独抽离出来,这样能减少后期的维护。但如果遇到此类需求,我们该如何解决?
方法
利用插槽的思想嵌入到文案中。下面介绍 react-i18next 和 vue-i18n的用法
react-i18next 和 vue-i18n 的引入使用这里不多赘述,直接说重点:
1. react-i18next
// component.js
import { Trans,useTranslation } from 'react-i18next';
const { t } = useTranslation()
<Trans
i18nKey='question' // key
values={{ dynamic: t('here') }} // dynamic 变量名可以随便取 只要与翻译文案中的对应即可
components={[ // 你可以发现这里是个数组 如需要多个插槽也是可以的
<span
onClick={() => setVisibleContact(!visibleContact)}
className={'text-blue-600 hover:text-blue-800 undercursor-pointer'}
></span>
]}
/>
// i18n/en-US.json
// components数组中因为只有一个动态插入的文案, 所以第一个用<0></0> 第二个则<1></1>以此类推
"question": "Any questions for us? Please click <0>{{dynamic}}</0>."
"here": "here"
// i18n/zh-CN.json
"question": "遇到问题? 请点击<0>{{dynamic}}</0>."
"here": "这里"
2. vue-i18n
// component.vue
// path key值 place 对应插槽名
<i18n path="question" tag="div">
<span place="dynamic_1">
<b>{{ user.name }}</b> // 变量
</span>
<span place="dynamic_2">
<a target="_blank" href="https://baidu.com">{{t('login'}}</a>
</span>
</i18n>
// i18n/en-US.json
"question": "If you already have an account, click {dynamic_1} to take your package.If you do not have an account, click {dynamic_2}.",
"login":"login"
// i18n/zh-CN.json
"question": "如您已有账号, 点击{dynamic_1}去领取你的包裹。没有账号点击
{dynamic_2}。",
"login":"登录"