Vue I18n HTML-插值

Vue I18n HTML-Interpolation

我在 json 文件中有一系列所有产品功能的翻译。 en.json 中的每个语言环境字符串都以某种方式突出显示了字符串的某些部分,例如 bolditalic.

{
  "feature1": "bla bla bla <b>blabla</b> bla ... bla bla",
  "feature2": "<i>bla</i> bla <b>bla bla bla</b> bla ... <b>bla bla</b>"
}

我想在列表中呈现它们,但 不使用 v-html 因为不推荐这样做。

我尝试了 component interpolation 但它没有帮助,我尝试将 <b><i> 放在一个命名的插槽中但是它没有用,因为我试图把 opening 和将标签关闭到不同的命名插槽,并导致 无效 HTML 标记 .

{
  "feature1": "bla bla bla {b}blabla{bclose} bla ... bla bla",
  "feature2": "bla bla {b}bla bla bla{bclose} bla ... {b}bla bla{bclose}"
}
<template>
  <i18n
   tag="li"
   v-for="feature in $i18n.messages.en.features"
   path="features"
  >
    <template v-slot:b>
      <b>
    </template>
    <template v-slot:bclose>
      </b>
    </template>
    ...
  </i18n>
</template>

我试图达到的最终结果将如下所示

如果不使用 v-html,我如何实现我想要实现的目标??

您应该这样做的方法是将所有 HTML 保留在 <template> 块中,将所有文本保留在 i18n 中,并且您必须将这些字符串分开HTML 块分成单独的翻译:

<i18n tag="li" path="features">
  <b>{{ $t('bla bla') }}</b>
</i18n>
{
  "features": "lorem ipsum {0} ...",
  "bla bla": "bar baz"
}

这导致:

<li>lorem ipsum <b>bar baz</b> ...</li>

有点遗憾,您需要 bla bla 作为单独的词,但您需要它作为独立的块,您不能只是将 HTML 开始和结束标记转置到您的字符串中,因为这与不安全的字符串插值相同。

我认为如果您使用受信任的内容,使用 v-html 指令不是问题,例如,您的 i18n 文件在您的控制之下并由您托管。大多数 XSS 攻击或问题来自第三方请求,这似乎不是你的情况。您可以阅读有关此指令和 XSS here.

的更多信息

如果你有兴趣使用它,你可以按照这里建议的去做,基本上you have to sanitize the content first