使用 vuejs i18n 的多行文本

问题描述 投票:0回答:8

我正在使用 i18n 单文件组件为我的应用程序提供翻译支持。为此,我使用如下标签

<i18n>
{
  "fr": {
    "text": "blabla in french 
             blabla
             bla"
  },
  "en": {
    "text": "blabla in english
             bla"
  }
}
</i18n>

但是我有多行带有 html 格式的文本,如何对长 html 文本使用语言处理?

javascript html vue.js internationalization vue-i18n
8个回答
19
投票

#1。您可以使用反引号:

i18n 文件:

{
  text: `Content
  With some 
  Break lines`
}

#2。你可以结合使用js和css

{
  text: 'Content \n With some \n Break lines'
}

CSS:

.class {
   white-space: pre-line
}

#3。您可以使用 HTML 和 v-html(但要小心,因为如果不清理 HTML,您会导致 XSS 攻击!)

{
  text: 'Content <br /> With some <br /> Break lines'
}

模板:

<div v-html="yourI18nRule" />

在此处了解有关清理 HTML 的更多信息:

https://www.npmjs.com/package/sanitize-html


12
投票

在这里找到了一个非常酷的解决方案。 可以通过插值来实现这一点。在此示例中,{0}

 占位符将替换为您放入 
<i18n>
 标签中的内容。

en.json

{ "footer": "Built with Vue and Vue I18n{0}Powered by an excessive amount of coffee" }

页脚.vue

<template> <i18n path="footer" tag="p" class="footer"> <br /> </i18n> </template>
    

7
投票
您始终可以使用反引号:

<i18n> { "fr": { "text": `blabla in french blabla bla` }, "en": { "text": `blabla in english bla` } } </i18n>

不过,您会收到一些有关 POJO 字符串的(无害的)警告。


4
投票
尝试实现以下代码行,因为它对我有用:

<i18n> { "fr": { "text": "blabla in french <br /> blabla <br /> bla" }, "en": { "text": "blabla in english <br /> bla" } } </i18n> <span v-html="$t('text')"></span>
    

2
投票
您可以设置占位符并在翻译中多次使用它。在此示例中,我使用 {br},并且还有一个电子邮件地址占位符。

Body: "Email was sent to {EmailAddress}{br}{br}Please enter the validation code below.{br}{br}If you have not received this email, please check your spam folder.",
然后在 vue 组件中我把这个

<i18n-t tag="h3" keypath="Body"> <template v-slot:br><br /></template> <template v-slot:EmailAddress> [email protected] </template> </i18n-t>
    

1
投票
问题的“常见”解决方案都不适合我:

    基于 css 的解决方案(white-space: pre-line)需要将样式添加到每个需要换行的翻译元素。它使代码变得混乱,我个人希望文本和样式之间有清晰的分离。
  • 如上所述,基于 v-html 的解决方案可能很危险,特别是当您有多人处理区域设置消息时。
  • 我使用全局 .json 文件来存储区域设置消息,而 .yaml 格式不适合我。
话虽如此,我认为这个问题没有完美的解决方案,也许这就是 vue-i18n 可以改进的地方。 但对于我的用例,我找到了一个非常好的解决方案:我创建了一个围绕组件的自定义包装器,它允许我:

    通过添加 {br} 占位符将文本移动到新行(受 @GeekyMonkey 启发)
  1. 通过将 'paragraph-class' 属性传递给自定义包装器,从区域设置消息列表中创建样式段落。这对我来说很重要,因为我不仅仅是想将文本移动到新行,有时我希望段落之间具有相同的可自定义距离

I18nCustom.vue:

<template> <div> <i18n v-bind="$attrs" v-on="$listeners" :class="paragraphClass" v-for="idx in (Array.isArray(paragraphs) ? paragraphs : [paragraphs]).length" :key="`${path}.${idx - 1}`" :path="Array.isArray(paragraphs) ? `${path}.${idx - 1}` : path" > <template v-for="(_, name) in $slots" v-slot:[name]> <slot :name="name"/> </template> <template #br> <br> </template> </i18n> </div> </template> <script> export default { data: () => ({ paragraphs: null }), props: { path: { type: String, required: true }, paragraphClass: { type: String, default: '' }, }, mounted() { this.paragraphs = this.$t(this.path) } }; </script>

使用方法: 您可以像使用元素一样使用包装器:支持所有道具和插槽

en.json

{ "paragraphsNewLine": "line1{br}line2{br}line3{slot-example}{br}", "slotExample": "slot", "styledParagraphs": [ "paragraph1", "paragraph2", "paragraph3" ], }
在组件中:

<!-- new line example --> new line example: <i18n-custom tag="p" path="paragraphsNewLine" > <template #slot-example> <b> {{ $t('slotExample') }} </b> </template> </i18n-custom> <!-- styled paragraphs example --> styled paragraphs example: <i18n-custom tag="p" path="styledParagraphs" paragraph-class="mb-3" />

结果: the results


0
投票
您尝试过

yaml格式吗?您只需安装“yaml-loader”并按照文档中的说明修改 vue.config.js 文件。然后,你可以做类似的事情:

<i18n> fr: text: | blabla in french blabla bla en: text: | blabla in english bla </i18n>
    

0
投票
我正在使用Vuejs2和Vuetify 如果你使用 v-card-text 来渲染它,你可以简单地一个类:text-pre-wrap

<v-card-text v-show="!!message" class="text-pre-wrap"> {{ message }} </v-card-text>
现在这条消息可以包含新行
 它会分成新的几行

© www.soinside.com 2019 - 2024. All rights reserved.