Skip to content

API de Composition

L'introduction de setup et de l'API de Composition de Vue ouvre de nouvelles possibilités. Mais pour pouvoir tirer tout le potentiel de Vue I18n, nous devrons utiliser quelques nouvelles fonctions pour remplacer l'accès à this.

Nous avons décrit les fonctionnalités de Vue I18n en utilisant l'API héritée, qui est compatible avec vue-i18n v8.x. Voyons maintenant Vue I18n useI18n pour l'API de Composition.

Utilisation de base

Examinons l'utilisation de base de l'API de Composition de Vue I18n ! Ici, nous apprendrons l'utilisation de base en modifiant le code dans Premiers pas pour comprendre l'utilisation de base.

Pour composer avec useI18n dans setup de Vue 3, il y a une chose à faire : vous devez définir l'option legacy de la fonction createI18n sur false.

Voici un exemple d'ajout de l'option legacy à createI18n :

js
// ...
 
const i18n = VueI18n.createI18n({
  legacy: false, // vous devez définir `false`, pour utiliser l'API de Composition
  locale: 'ja',
  fallbackLocale: 'en',
  messages: {
    en: {
      message: {
        hello: 'hello world'
      }
    },
    ja: {
      message: {
        hello: 'こんにちは、世界'
      }
    }
  }
})

// ...

Vous pouvez définir legacy: false pour permettre à Vue I18n de basculer le mode d'API, du mode API hérité au mode API de Composition.

NOTE

Les propriétés suivantes de l'instance i18n créée par createI18n changent son comportement :

  • Propriété mode : "legacy" à "composition"
  • Propriété global : instance VueI18n à instance Composer

Vous êtes maintenant prêt à utiliser useI18n dans le composant App.vue. Le code ressemble à ceci :

vue
<script setup> 
import { useI18n } from 'vue-i18n'
const { t } = useI18n() 
</script> // [!code ++]

<template>
  <h1>{{ $t("message.hello") }}</h1>
</template>

Vous devez appeler useI18n en haut de <script setup>.

useI18n retourne une instance Composer. L'instance Composer fournit une API de traduction telle que la fonction t, ainsi que des propriétés telles que locale et fallbackLocale, tout comme l'instance VueI18n. Pour plus d'informations sur l'instance Composer, voir la Référence de l'API.

Dans l'exemple ci-dessus, il n'y a pas d'options pour useI18n, donc il retourne une instance Composer qui travaille avec la portée globale. Cela signifie qu'il retourne une instance Composer qui travaille avec la portée globale, ce qui signifie que le message localisé référencé par la fonction t ici est celui spécifié dans createI18n.

vous pouvez utiliser t dans le template des composants :

vue
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>

<template>
  <h1>{{ $t("message.hello") }}</h1> // [!code --]
  <h1>{{ t("message.hello") }}</h1> // [!code ++]
</template>

La sortie suit :

vue
<div id="app">
  <h1>こんにちは、世界</h1>
</div>

Traduction des messages

Dans le mode de l'API héritée, les messages étaient traduits en utilisant soit $t soit l'instance VueI18n de t.

Dans le mode de l'API de Composition, la syntaxe de format de message reste la même que dans le mode de l'API héritée. Vous pouvez utiliser le t de l'instance Composer pour traduire un message comme suit :

vue
<script setup>
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'

const { t } = useI18n({
  locale: 'en',
  messages: {
    en: {
      msg: 'hello',
      named: '{msg} world!',
      list: '{0} world!',
      literal: "{'hello'} world!",
      the_world: 'the world',
      dio: 'DIO:',
      linked: '@:dio @:the_world !!!!'
    },
    ja: {
      msg: 'こんにちは',
      named: '{msg} 世界!',
      list: '{0} 世界!',
      literal: "{'こんにちは'} 世界!",
      the_world: 'ザ・ワールド!',
      dio: 'ディオ:',
      linked: '@:dio @:the_world !!!!'
    }
  }
})

const msg = computed(() => t('msg'))
</script>

<template>
  <p>{{ t('named', { msg }) }}</p>
  <p>{{ t('list', [msg]) }}</p>
  <p>{{ t('literal') }}</p>
  <p>{{ t('linked') }}</p>
</template>

Pour plus de détails sur t, voir la Référence de l'API

Pluralisation

Dans le mode de l'API de Composition, la forme plurielle du message est conservée dans la syntaxe comme dans le mode de l'API héritée, mais est traduite en utilisant le t de l'instance Composer :

vue
<script setup>
import { useI18n } from 'vue-i18n'

const { t } = useI18n({
  locale: 'en',
  messages: {
    en: {
      car: 'car | cars',
      apple: 'no apples | one apple | {count} apples',
      banana: 'no bananas | {n} banana | {n} bananas'
    }
  }
})
</script>

<template>
  <h2>Car:</h2>
  <p>{{ t('car', 1) }}</p>
  <p>{{ t('car', 2) }}</p>
  <h2>Apple:</h2>
  <p>{{ t('apple', 0) }}</p>
  <p>{{ t('apple', 1) }}</p>
  <p>{{ t('apple', { count: 10 }, 10) }}</p>
  <p>{{ t('apple', 10) }}</p>
  <h2>Banana:</h2>
  <p>{{ t('banana', { n: 1 }, 1) }}</p>
  <p>{{ t('banana', 1) }}</p>
  <p>{{ t('banana', { n: 'too many' }, 100) }}</p>
</template>

NOTE

Dans le mode de l'API de Composition, les traductions au pluriel ont été intégrées dans t.

Mise en forme de la date et de l'heure

Dans le mode de l'API héritée, les valeurs de date et d'heure étaient formatées en utilisant $d ou l'instance VueI18n de d.

Dans le mode de l'API de Composition, cela utilise le d de l'instance Composer pour le formatage :

vue
<script setup>
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'

const { t, d } = useI18n({
  locale: 'en-US',
  messages: {
    'en-US': {
      current: 'Current Datetime'
    }
  },
  datetimeFormats: {
    'en-US': {
      long: {
        year: 'numeric',
        month: '2-digit',
        day: '2-digit',
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit'
      }
    }
  }
})

const now = ref(new Date())
</script>

<template>
  <p>{{ t('current') }}: {{ d(now, 'long') }}</p>
</template>

Pour plus de détails sur d, voir la Référence de l'API

Mise en forme des nombres

Dans le mode de l'API héritée, les valeurs numériques étaient formatées en utilisant $n ou le n de l'instance VueI18n.

Dans le mode de l'API de Composition, cela est formaté en utilisant le n de l'instance Composer :

vue
<script setup>
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'

const { t, n } = useI18n({
  locale: 'en-US',
  messages: {
    'en-US': {
      money: 'Money'
    }
  },
  numberFormats: {
    'en-US': {
      currency: {
        style: 'currency',
        currency: 'USD'
      }
    }
  }
})

const money = ref(1000)
</script>

<template>
  <p>{{ t('money') }}: {{ n(money, 'currency') }}</p>
</template>

Pour plus de détails sur n, voir la Référence de l'API

Portée globale

Une portée globale dans le mode de l'API de Composition est créée lorsqu'une instance i18n est créée avec createI18n, de manière similaire au mode de l'API héritée.

Alors que la propriété global du mode de l'API héritée de l'instance i18n est l'instance VueI18n, le mode de l'API de Composition permet de référencer l'instance Composer.

Il existe deux façons de référencer l'instance Composer de portée globale dans le composant.

Explicite avec useI18n

Comme nous l'avons expliqué, dans useI18n est une façon.

ts
import { useI18n } from 'vue-i18n'

const { t } = useI18n({ useScope: 'global' })

// Quelque chose à faire ici ...

Le code ci-dessus définit l'option useI18n à useScope: 'global', ce qui permet à useI18n de retourner une instance Composer qui peut être accédée par la propriété global de l'instance i18n. L'instance Composer est une portée globale.

Ensuite, vous pouvez composer en utilisant les fonctions et propriétés exposées depuis l'instance Composer.

NOTE

Si vous définissez useI18n à messages, datetimeFormats, et numberFormats ensemble avec useScope: 'global', elles seront fusionnées dans la portée globale. Cela signifie qu'elles seront gérées par messages, datetimeFormasts, et numberFormats de l'instance Composer de portée globale.

Et aussi, si global est spécifié dans les blocs personnalisés i18n (par exemple <i18n global>{ … }</i18n>), les messages de locale définis dans les blocs sont fusionnés avec la portée globale.

Implicite avec les propriétés et fonctions injectées

Une autre façon de référencer une instance Composer de portée globale est par le biais de propriétés et de fonctions implicitement injectées dans le composant.

Vous devez spécifier globalInjection: true ensemble avec legacy: false comme option pour createI18n, car c'est désactivé par défaut.

NOTE

vue-i18n v9.2-beta.34 ou ultérieur, globalInjection est true par défaut.

Cela permet à Vue I18n d'injecter les propriétés et fonctions suivantes dans les composants :

  • $i18n : Un objet enveloppé avec les propriétés de l'instance Composer de portée globale
    • locale
    • fallbackLocale
    • availableLocales
  • $t : Fonction t de Composer qui est de portée globale
  • $rt : Fonction rt de Composer qui est de portée globale
  • $d : Fonction d de Composer qui est de portée globale
  • $n : Fonction n de Composer qui est de portée globale
  • $tm : Fonction tm de Composer qui est de portée globale

Le runtime Vue 3 injecte globalement les composants avec ce qui est défini dans app.config.globalProperties. Ainsi, ceux listés ci-dessus sont injectés par le runtime Vue 3 et peuvent donc être utilisés implicitement dans le template.

NOTICE

  • Le setup ne permet pas de voir ces propriétés et fonctions injectées dans le composant
  • Dans le mode de l'API héritée, certaines API Vue I18n préfixées par $ étaient injectées, mais les propriétés et fonctions préfixées par $ et injectées dans le mode de l'API de Composition sont différentes du mode de l'API héritée.

Vous avez remarqué que celles listées ci-dessus sont préfixées par $. La raison pour laquelle elles sont préfixées par $ est que :

  • Le setup ne entre pas en conflit avec les propriétés et fonctions retournées par le contexte de rendu
  • Identifiant accessible globalement pour le mode de l'API de Composition de Vue I18n

En faisant cela, l'utilisateur est informé qu'il s'agit de propriétés et fonctions spéciales.

NOTICE

Si votre application Vue n'utilise pas de portée locale et fait tout le i18n dans la portée globale, c'est très utile car il n'est pas nécessaire d'exécuter useI18n dans le setup pour chaque composant. Cependant, cette méthode présente le problème des variables globales de nature similaire. Vous devez l'utiliser avec prudence, surtout pour les grandes applications Vue.

Si vous l'utilisez une fois et arrêtez de l'utiliser, vous devez changer toutes les propriétés ou fonctions utilisées dans les templates vers celles du contexte de setup retournées avec le setup en utilisant useI18n avec l'option useScope: 'global'.

Portée locale

Dans le mode de l'API héritée, l'instance VueI18n était créée en spécifiant l'option de composant i18n pour chaque composant. Cela permet aux ressources telles que les messages locaux gérés par l'instance VueI18n d'être des portées locales qui ne peuvent être référencées que par le composant cible.

Pour activer la portée locale dans le mode de l'API de Composition, vous devez définir une option à useI18n, qui créera une nouvelle instance de Composer basée sur la locale donnée, les messages de locale, etc. Lorsque l'option est donnée, useI18n crée et retourne une nouvelle instance de Composer basée sur la locale, les messages de locale et autres ressources spécifiées par l'option.

NOTE

Vous pouvez spécifier explicitement l'option useScope: 'local'.

Voici les exemples de code :

js
import { useI18n } from 'vue-i18n'

const { t, d, n, tm, locale } = useI18n({
  locale: 'ja-JP',
  fallbackLocale: 'en-US',
  messages: {
    'en-US': {
      // ....
    },
    'ja-JP': {
      // ...
    }
  },
  datetimeFormats: {
    'en-US': {
      // ....
    },
    'ja-JP': {
      // ...
    }
  },
  numberFormats: {
    'en-US': {
      // ....
    },
    'ja-JP': {
      // ...
    }
  }
})

// Something to do here ...

Messages de locale

Si vous utilisez les blocs personnalisés i18n dans les SFC comme ressource de messages de locale, ils seront fusionnés avec les messages de locale spécifiés par l'option messages de useI18n.

Voici un exemple d'utilisation des blocs personnalisés i18n et des options useI18n :

vue
<script setup>
import { useI18n } from 'vue-i18n'
import en from './en.json'

const { t, availableLocales, getLocaleMessages } = useI18n({
  locale: 'en',
  messages: {
    en
  }
})

availableLocales.forEach(locale => {
  console.log(`${locale} locale messages`, getLocaleMessages(locale))
})
</script>

<i18n locale="ja">
{
  "hello": "こんにちは!"
}
</i18n>

NOTE

Dans cet exemple, la définition des ressources est séparée des blocs personnalisés i18n et de l'option messages de useI18n, mais dans la portée locale, les messages de ressource sont spécifiés dans l'option messages en un seul bloc pour des raisons administratives sur les messages de ressource ou définir tous les messages de ressource dans les blocs personnalisés i18n, ce qui est préférable.

Messages de locale partagés pour les composants

Dans le mode de l'API héritée, les messages de locale partagés sont utilisés dans les composants avec l'option sharedMessages.

Dans le mode de l'API de Composition, utilisez mergeLocaleMessage exporté par useI18n.

Exemple de messages de locale communs :

js
export default {
  en: {
    buttons: {
      save: "Save",
      // ...
    }
  },
  ja: {
    buttons: {
      save: "保存",
      // ...
    }
  }
}

utilisez mergeLocaleMessage sur les composants :

vue
<script setup>
import { useI18n } from 'vue-i18n'
import commonMessages from './locales/common'

const { t, mergeLocaleMessage } = useI18n({
  locale: 'en',
  messages: {
    en: {
      hello: 'Hello!'
    },
    ja: {
      hello: 'こんにちは!'
    }
  }
})

for (const locale of ['en', 'ja']) {
  mergeLocaleMessage(locale, commonMessages[locale])
}
</script>

Changement de locale

Portée globale

Vous voulez changer la locale avec <script setup>, il suffit d'obtenir un Composer global avec useI18n et de le changer en utilisant la propriété locale de l'instance.

vue
<script setup>
const { t, locale } = useI18n({ useScope: 'global' })

locale.value = 'en' // change !
</script>

Et vous pouvez également utiliser le contexte de setup dans le template, ce qui peut être changé comme suit :

vue
<select v-model="locale">
  <option value="en">en</option>
  <option value="ja">ja</option>
</select>

Lorsque vous changez la locale de la portée globale, les composants qui dépendent de la portée globale, tels que l'API de traduction t, peuvent fonctionner de manière réactive et basculer les messages d'affichage vers ceux de la locale cible.

Si vous utilisez la façon implicite, vous pouvez également le changer dans le template avec $i18n.locale, comme suit :

vue
<select v-model="$i18n.locale">
  <option value="en">en</option>
  <option value="ja">ja</option>
</select>

Portée locale

Les locales de la portée locale, c'est-à-dire la propriété locale de l'instance Composer retournée par useI18n, sont héritées de la portée globale, comme dans l'API héritée. Par conséquent, lorsque vous changez la locale à la portée globale, la locale héritée de la portée locale est également changée. Si vous voulez basculer la locale pour toute l'application, vous pouvez utiliser le locale retourné par useI18n({ useScope: 'global' }) ou, si vous utilisez la façon implicite, vous pouvez utiliser $i18n.locale.

NOTE

Si vous ne souhaitez pas hériter de la locale de la portée globale, l'option inheritLocale de useI18n doit être false.

NOTICE

Les modifications apportées à la locale à la portée locale n'ont aucun effet sur la locale de la portée globale, mais seulement dans la portée locale.

Correspondance entre l'instance VueI18n et l'instance Composer

L'API offerte par l'instance Composer dans l'API de Composition est très similaire à l'interface de l'API fournie par l'instance VueI18n.

MEMO

Interne, l'instance VueI18n du mode de l'API héritée fonctionne en enveloppant l'instance Composer. Pour cette raison, la charge de performance est moindre dans le mode de l'API de Composition que dans le mode de l'API héritée.

Voici le tableau de correspondance :

Instance VueI18nInstance Composer
idid
localelocale
fallbackLocalefallbackLocale
availableLocalesavailableLocales
messagesmessages
datetimeFormatsdatetimeFormats
numberFormatsnumberFormats
modifiersmodifiers
missinggetMissingHandler / setMissingHandler
postTranslationgetPostTranslationHandler / setPostTranslationHandler
silentTranslationWarnmissingWarn
silentFallbackWarnfallbackWarn
formatFallbackMessagesfallbackFormat
syncinheritLocale
warnHtmlInMessagewarnHtmlMessage
escapeParameterHtmlescapeParameter
tt
tct
tete
tmtm
getLocaleMessagegetLocaleMessage
setLocaleMessagesetLocaleMessage
mergeLocaleMessagemergeLocaleMessage
dd
getDateTimeFormatgetDateTimeFormat
setDateTimeFormatsetDateTimeFormat
mergeDateTimeFormatmergeDateTimeFormat
nn
getNumberFormatgetNumberFormat
setNumberFormatsetNumberFormat
mergeNumberFormatmergeNumberFormat