组件插值

基本用法

支持版本

🆕 7.0 新增

有时,我们需要使用包含 HTML 标签或组件的语言环境信息进行本地化。例如:

  1. <p>I accept xxx <a href="/term">Terms of Service Agreement</a></p>

在上面的信息中,如果你使用 $t,可能你会尝试编写以下语言环境信息:

  1. const messages = {
  2. en: {
  3. term1: 'I Accept xxx\'s',
  4. term2: 'Terms of Service Agreement'
  5. }
  6. }

你可能会尝试在以下模板中实现:

  1. <p>{{ $t('term1') }}<a href="/term">{{ $t('term2') }}</a></p>

输出:

  1. <p>I accept xxx <a href="/term">Terms of Service Agreement</a></p>

这是非常麻烦的,如果在语言环境信息中配置 <a> 标签,则可能由于使用了 v-html="$t('term')" 进行本地化而存在被 XSS 攻击的可能性。

你可以使用 i18n 函数式组件来避免它。例如:

  1. <div id="app">
  2. <!-- ... -->
  3. <i18n path="term" tag="label" for="tos">
  4. <a :href="url" target="_blank">{{ $t('tos') }}</a>
  5. </i18n>
  6. <!-- ... -->
  7. </div>
  1. const messages = {
  2. en: {
  3. tos: 'Term of Service',
  4. term: 'I accept xxx {0}.'
  5. },
  6. ja: {
  7. tos: '利用規約',
  8. term: '私は xxx の{0}に同意します。'
  9. }
  10. }
  11. const i18n = new VueI18n({
  12. locale: 'en',
  13. messages
  14. })
  15. new Vue({
  16. i18n,
  17. data: {
  18. url: '/term'
  19. }
  20. }).$mount('#app')

输出如下:

  1. <div id="app">
  2. <!-- ... -->
  3. <label for="tos">
  4. I accept xxx <a href="/term" target="_blank">Term of Service</a>.
  5. </label>
  6. <!-- ... -->
  7. </div>

关于上面的例子,见示例组件插值 - 图1

i18n 函数式组件的子元素用 path 属性的语言环境信息进行插值。在上面的例子中,

<a :href="url" target="_blank">{{ $t('tos') }}</a>

被插入了语言环境信息 term

在上面的示例中,组件插值遵循列表格式i18n 函数式组件的子项按其出现顺序进行插值。

高级用法

支持版本

🆕 7.2 新增

提示

⚠️ 在 i18n 组件中,仅包含空格的文本内容将被省略。

place 特性的帮助下支持具名格式。例如:

  1. <div id="app">
  2. <!-- ... -->
  3. <i18n path="info" tag="p">
  4. <span place="limit">{{ changeLimit }}</span>
  5. <a place="action" :href="changeUrl">{{ $t('change') }}</a>
  6. </i18n>
  7. <!-- ... -->
  8. </div>
  1. const messages = {
  2. en: {
  3. info: 'You can {action} until {limit} minutes from departure.',
  4. change: 'change your flight',
  5. refund: 'refund the ticket'
  6. }
  7. }
  8. const i18n = new VueI18n({
  9. locale: 'en',
  10. messages
  11. })
  12. new Vue({
  13. i18n,
  14. data: {
  15. changeUrl: '/change',
  16. refundUrl: '/refund',
  17. changeLimit: 15,
  18. refundLimit: 30
  19. }
  20. }).$mount('#app')

输出:

  1. <div id="app">
  2. <!-- ... -->
  3. <p>
  4. You can <a href="/change">change your flight</a> until <span>15</span> minutes from departure.
  5. </p>
  6. <!-- ... -->
  7. </div>

提示

⚠️ i18n 组件的所有子项都必须设置 place 属性。否则它将回退到列表格式。

如果你仍想在命名格式中插入文本内容,可以在 i18n 组件上定义 places 属性。例如:

  1. <div id="app">
  2. <!-- ... -->
  3. <i18n path="info" tag="p" :places="{ limit: refundLimit }">
  4. <a place="action" :href="refundUrl">{{ $t('refund') }}</a>
  5. </i18n>
  6. <!-- ... -->
  7. </div>

输出:

  1. <div id="app">
  2. <!-- ... -->
  3. <p>
  4. You can <a href="/refund">refund your ticket</a> until 30 minutes from departure.
  5. </p>
  6. <!-- ... -->
  7. </div>