Interpolation des composants
Utilisation de base
Parfois, nous devons localiser avec un message de localisation qui a été inclus dans une balise HTML ou un composant. Par exemple :
<p>J'accepte xxx <a href="/term">Conditions d'utilisation</a></p>Dans le message ci-dessus, si vous utilisez $t, vous essayez probablement de composer les messages de localisation suivants :
const messages = {
en: {
term1: 'J\'accepte les',
term2: 'Conditions d\'utilisation'
}
}Et votre modèle localisé peut ressembler à cela :
<p>{{ $t('term1') }}<a href="/term">{{ $t('term2') }}</a></p>Résultat :
<p>J'accepte xxx <a href="/term">Conditions d'utilisation</a></p>C'est très fastidieux, et si vous configurez la balise <a> dans un message de localisation, il existe un risque de vulnérabilités XSS en raison de la localisation avec v-html="$t('term')".
Vous pouvez l'éviter en utilisant le composant de traduction (i18n-t). Par exemple le code ci-dessous.
Modèle :
<div id="app">
<!-- ... -->
<i18n-t keypath="term" tag="label" for="tos">
<a :href="url" target="_blank">{{ $t('tos') }}</a>
</i18n-t>
<!-- ... -->
</div>JavaScript :
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
const i18n = createI18n({
locale: 'en',
messages: {
en: {
tos: 'Conditions d\'utilisation',
term: 'J\'accepte xxx {0}.'
},
ja: {
tos: '利用規約',
term: '私は xxx の{0}に同意します。'
}
}
})
const app = createApp({
data: () => ({ url: '/term' })
})
app.use(i18n)
app.mount('#app')Le résultat obtenu :
<div id="app">
<!-- ... -->
<label for="tos">
J'accepte xxx <a href="/term" target="_blank">Conditions d'utilisation</a>.
</label>
<!-- ... -->
</div>À propos de l'exemple ci-dessus, voir l'exemple
Les enfants du composant de traduction sont interpolés avec le message de localisation de la propriété keypath. Dans l'exemple ci-dessus,
<a :href="url" target="_blank">{{ $t('tos') }}</a>
Est interpolé avec le message de localisation term.
Dans l'exemple ci-dessus, l'interpolation des composants suit l'interpolation de liste. Les enfants du composant de traduction sont interpolés selon leur ordre d'apparition.
Vous pouvez choisir le type d'élément racine en spécifiant une propriété tag. Si omis, la valeur par défaut est Fragments.
Utilisation de la syntaxe des slots
Il est plus pratique d'utiliser la syntaxe des slots nommés. Par exemple :
Modèle :
<div id="app">
<!-- ... -->
<i18n-t keypath="info" tag="p">
<template v-slot:limit>
<span>{{ changeLimit }}</span>
</template>
<template v-slot:action>
<a :href="changeUrl">{{ $t('change') }}</a>
</template>
</i18n-t>
<!-- ... -->
</div>JavaScript :
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
const i18n = createI18n({
locale: 'en',
messages: {
en: {
info: 'Vous pouvez {action} jusqu\'à {limit} minutes avant le départ.',
change: 'changer votre vol',
refund: 'rembourser le billet'
}
}
})
const app = createApp({
data: () => ({
changeUrl: '/change',
refundUrl: '/refund',
changeLimit: 15,
refundLimit: 30
})
})
app.use(i18n)
app.mount('#app')Résultat :
<div id="app">
<!-- ... -->
<p>
Vous pouvez <a href="/change">changer votre vol</a> jusqu'à <span>15</span> minutes avant le départ.
</p>
<!-- ... -->
</div>Vous pouvez également utiliser le raccourci de slots suivant dans les modèles :
<div id="app">
<!-- ... -->
<i18n-t keypath="info" tag="p">
<template #limit>
<span>{{ changeLimit }}</span>
</template>
<template #action>
<a :href="changeUrl">{{ $t('change') }}</a>
</template>
</i18n-t>
<!-- ... -->
</div>LIMITATION
⚠️ Dans le composant de traduction, les props des slots ne sont pas prises en charge.
Utilisation de la pluriel
Vous pouvez utiliser la pluriel dans l'interpolation des composants en utilisant la propriété plural. Par exemple :
Modèle :
<div id="app">
<!-- ... -->
<i18n-t keypath="message.plural" locale="en" :plural="count">
<template #n>
<b>{{ count }}</b>
</template>
</i18n-t>
<!-- ... -->
</div>JavaScript :
const { createApp, ref } = Vue
const { createI18n } = VueI18n
const i18n = createI18n({
legacy: false,
locale: 'en',
messages: {
en: {
message: {
plural: 'pas de bananes | {n} banane | {n} bananes'
}
}
}
})
const app = createApp({
setup() {
const count = ref(2)
return { count }
}
})
app.use(i18n)
app.mount('#app')Le résultat obtenu :
<div id="app" data-v-app="">
<!-- ... -->
<b>2</b> bananes
<!-- ... -->
</div>Résolution de portée
La résolution de portée du composant de traduction est parent par défaut.
Cela signifie que le composant de traduction utilise la portée activée dans le composant parent qui l'utilise.
Si le composant parent a useI18n avec useScope: 'global', il utilisera la Portée Globale, sinon si useScope: 'local', il utilisera la Portée Locale du composant parent.
Cependant, vous rencontrez parfois le message d'avertissement dans la console de votre navigateur :
[intlify] Portée parente non trouvée. Utilisation de la portée globale.Ce message est affiché lorsque vous n'avez pas exécuté useI18n dans le composant parent qui utilise le composant de traduction.
Dans ce cas, la portée du composant de traduction retombera sur la portée globale comme indiqué dans le message d'avertissement.
Une solution de contournement pour supprimer cet avertissement est de spécifier global comme propriété scope du composant de traduction.
<i18n-t keypath="message.foo" scope="global">
...
</i18n-t>NOTE
Cet avertissement n'est pas affiché dans la console du navigateur lors des builds de production.
NOTE
Cela n'est pas disponible dans petite-vue-i18n