API de Composición
La introducción de setup y la API de Composición de Vue abre nuevas posibilidades. Pero para poder aprovechar al máximo Vue I18n, necesitaremos usar algunas nuevas funciones para reemplazar el acceso a this.
Hemos estado describiendo las características de Vue I18n usando la API heredada, que es compatible con vue-i18n v8.x. Ahora veamos useI18n de Vue I18n para la API de Composición.
Uso Básico
¡Vamos a ver el uso básico de la API de Composición de Vue I18n! Aquí aprenderemos el uso básico modificando el código en Empezando para aprender el uso básico.
Para componer con useI18n en setup de Vue 3, hay una cosa que debe hacerse: necesita establecer la opción legacy de la función createI18n a false.
El siguiente es un ejemplo de agregar la opción legacy a createI18n:
// ...
const i18n = VueI18n.createI18n({
legacy: false, // debe establecer `false` para usar la API de Composición
locale: 'ja',
fallbackLocale: 'en',
messages: {
en: {
message: {
hello: 'hello world'
}
},
ja: {
message: {
hello: 'こんにちは、世界'
}
}
}
})
// ...Puede establecer legacy: false para permitir que Vue I18n cambie el modo de la API, del modo de API heredado al modo de API de Composición.
NOTA
Las siguientes propiedades de la instancia i18n creada por createI18n cambian su comportamiento:
- Propiedad
mode:"legacy"a"composition" - Propiedad
global: instancia de VueI18n a instancia de Composer
Ahora está listo para usar useI18n en el componente App.vue. El código se ve así:
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script> // [!code ++]
<template>
<h1>{{ $t("message.hello") }}</h1>
</template>Debe llamar a useI18n al inicio de <script setup>.
useI18n devuelve una instancia de Composer. La instancia de Composer proporciona una API de traducción como la función t, así como propiedades como locale y fallbackLocale, tal como la instancia de VueI18n. Para más información sobre la instancia de Composer, vea la Referencia de API.
En el ejemplo anterior, no hay opciones para useI18n, por lo tanto devuelve una instancia de Composer que funciona con el alcance global. Como tal, devuelve una instancia de Composer que funciona con el alcance global, lo que significa que el mensaje localizado referenciado por la función t aquí es el especificado en createI18n.
Puede usar t en la plantilla de los componentes:
<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 salida es:
<div id="app">
<h1>こんにちは、世界</h1>
</div>Traducción de Mensajes
En el modo de API heredado, los mensajes eran traducidos usando $t o la instancia de VueI18n de t.
En el modo de API de Composición, la sintaxis de formato de mensaje permanece igual que en el modo de API heredado. Puede usar la función t de la instancia de Composer para traducir un mensaje como sigue:
<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>Para más detalles de t, vea la Referencia de API
Pluralización
En el modo de API de Composición, la forma plural del mensaje se deja en sintaxis como en el modo de API heredado, pero se traduce usando la función t de la instancia de Composer:
<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>NOTA
En el modo de API de Composición, las traducciones plurales han sido integradas en t.
Formateo de Fecha/Hora
En el modo de API heredado, el valor de fecha/hora se formateaba usando $d o la instancia de VueI18n de d.
En el modo de API de Composición, usa la función d de la instancia de Composer para formatear:
<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>Para más detalles de d, vea la Referencia de API
Formateo de Números
En el modo de API heredado, el valor numérico se formatea usando $n o la función n de la instancia de VueI18n.
En el modo de API de Composición, se formatea usando la función n de la instancia de Composer:
<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>Para más detalles de n, vea la Referencia de API
Ámbito Global
Un ámbito global en el modo de API de Composición se crea cuando se crea una instancia i18n con createI18n, similar al modo de API heredado.
Mientras que la propiedad global del modo de API heredado de la instancia i18n es la instancia de VueI18n, el modo de API de Composición le permite referenciar la instancia de Composer.
Hay dos formas de referirse a la instancia de Composer del ámbito global en el componente.
Explícito con useI18n
Como explicamos, en useI18n es una manera.
import { useI18n } from 'vue-i18n'
const { t } = useI18n({ useScope: 'global' })
// Algo que hacer aquí...El código anterior establece la opción useI18n a useScope: 'global', lo cual permite que useI18n devuelva una instancia de Composer que puede ser accedida por la propiedad global de la instancia i18n. La instancia de Composer es un ámbito global.
Entonces puede componer usando las funciones y propiedades expuestas desde la instancia de Composer.
NOTA
Si configura useI18n con messages, datetimeFormats, y numberFormats junto con useScope: 'global', serán fusionados al ámbito global. Es decir, serán gestionados por messages, datetimeFormasts, y numberFormats de la instancia de Composer del ámbito global.
Y también, si global se especifica en bloques i18n personalizados (por ejemplo <i18n global>{ … }</i18n>), los mensajes de idioma definidos en los bloques se fusionan con el ámbito global.
Implícito con propiedades e instrucciones inyectadas
Otra forma de referirse a la instancia de Composer del ámbito global es a través de propiedades y funciones inyectadas implícitamente en el componente.
Necesita especificar globalInjection: true junto con legacy: false como opción para createI18n, porque está deshabilitado por defecto.
NOTA
vue-i18n v9.2-beta.34 o posterior, globalInjection es true por defecto.
Esto permite que Vue I18n inyecte las siguientes propiedades y funciones en los componentes:
$i18n: Un objeto envuelto con las siguientes propiedades de la instancia de Composer del ámbito globallocalefallbackLocaleavailableLocales
$t: Funcióntde Composer que es del ámbito global$rt: Funciónrtde Composer que es del ámbito global$d: Funcióndde Composer que es del ámbito global$n: Funciónnde Composer que es del ámbito global$tm: Funcióntmde Composer que es del ámbito global
El tiempo de ejecución de Vue 3 inyecta globalmente componentes con lo establecido en app.config.globalProperties. Por lo tanto, los elementos enumerados arriba son inyectados por el tiempo de ejecución de Vue 3 y pueden ser usados implícitamente en plantillas.
AVISO
setupno permite ver estas propiedades y funciones inyectadas en el componente- En el modo de API heredado, algunas APIs de Vue I18n con prefijo
$fueron inyectadas, pero las propiedades y funciones con prefijo$e inyectadas en el modo de API de Composición son diferentes del modo de API heredado.
Ha notado que los elementos enumerados arriba tienen prefijo $. La razón por la cual se les da prefijo $ es porque:
setupno entra en conflicto con las propiedades y funciones devueltas por el contexto de renderizado- Identificador accesible en el ámbito global para el modo de API de Composición de Vue I18n
Haciendo esto, el usuario se hace consciente de que son propiedades y funciones especiales.
AVISO
Si su aplicación Vue no usa ámbito local y hace todo i18n en ámbito global, esto es muy útil ya que no necesita ejecutar useI18n en setup para cada componente. Sin embargo, este método tiene el problema de variables globales del mismo tipo. Debe usarse con cautela, especialmente en grandes aplicaciones Vue.
Si lo usa una vez y deja de usarlo, debe cambiar todas las propiedades o funciones usadas en plantillas a las devueltas por setup usando useI18n con la opción useScope: 'global'.
Ámbito Local
En el modo de API heredado, la instancia de VueI18n se crea especificando la opción de componente i18n para cada componente. Esto permite que recursos como mensajes locales gestionados por la instancia de VueI18n sean ámbitos locales que solo puedan ser referenciados por el componente objetivo.
Para habilitar el ámbito local en el modo de API de Composición, necesita establecer una opción a useI18n, que creará una nueva instancia de Composer basada en el locale dado, los mensajes de locale, etc. Cuando se da la opción, useI18n crea y devuelve una nueva instancia de Composer basada en el locale, los mensajes de locale y otros recursos especificados por la opción.
NOTA
Puede especificar explícitamente la opción useScope: 'local'.
Los siguientes códigos de ejemplo:
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': {
// ...
}
}
})
// Algo que hacer aquí...Mensajes Locales
Si usa bloques i18n personalizados en SFC como recurso de mensajes locales, será fusionado con los mensajes locales especificados por la opción messages de useI18n.
El siguiente es un ejemplo de usar bloques i18n personalizados y opciones de useI18n:
<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} mensajes de locale`, getLocaleMessages(locale))
})
</script>
<i18n locale="ja">
{
"hello": "こんにちは!"
}
</i18n>NOTA
En este ejemplo, la definición de recursos está separada de los bloques i18n personalizados y la opción messages de useI18n, pero en el ámbito local, los mensajes de recursos se especifican en la opción messages en conjunto por motivos administrativos o define todos los mensajes de recursos en los bloques i18n personalizados, lo cual es preferible.
Mensajes Locales Compartidos para Componentes
En el modo de API heredado, los mensajes locales compartidos se usan en componentes con la opción sharedMessages.
En el modo de API de Composición, use mergeLocaleMessage exportado por useI18n.
Ejemplo de mensajes locales comunes:
export default {
en: {
buttons: {
save: "Guardar",
// ...
}
},
ja: {
buttons: {
save: "保存",
// ...
}
}
}Uso de mergeLocaleMessage en Componentes:
<script setup>
import { useI18n } from 'vue-i18n'
import commonMessages from './locales/common'
const { t, mergeLocaleMessage } = useI18n({
locale: 'en',
messages: {
en: {
hello: '¡Hola!'
},
ja: {
hello: 'こんにちは!'
}
}
})
for (const locale of ['en', 'ja']) {
mergeLocaleMessage(locale, commonMessages[locale])
}
</script>Cambio de Idioma
Ámbito Global
Quiere cambiar el idioma con <script setup>, simplemente obtenga un Composer global con useI18n y cámbielo usando la propiedad locale de la instancia.
<script setup>
const { t, locale } = useI18n({ useScope: 'global' })
locale.value = 'en' // ¡cambiar!
</script>Y también puede usar el contexto de setup en la plantilla, que puede cambiarse como sigue:
<select v-model="locale">
<option value="en">en</option>
<option value="ja">ja</option>
</select>Cuando cambie el idioma del ámbito global, componentes que dependen del ámbito global, como la API de traducción t, pueden funcionar reactivamente y cambiar los mensajes mostrados a los del idioma objetivo.
Si usa la forma implícita, también puede cambiarlo en la plantilla con $i18n.locale, como sigue:
<select v-model="$i18n.locale">
<option value="en">en</option>
<option value="ja">ja</option>
</select>Ámbito Local
Los idiomas del ámbito local, es decir, la propiedad locale de la instancia de Composer devuelta por useI18n, se heredan del ámbito global, al igual que el modo de API heredado. Por lo tanto, cuando cambie el idioma en el ámbito global, el idioma del ámbito local heredado también cambia. Si quiere cambiar el idioma para toda la aplicación, puede usar la locale devuelta por useI18n({ useScope: 'global' }) o, si usa la forma implícita, puede usar $i18n.locale.
NOTA
Si no desea heredar el idioma del ámbito global, la opción inheritLocale de useI18n debe ser false.
AVISO
Los cambios en la locale en el ámbito local no tienen efecto en la localización del ámbito global, sino solo dentro del ámbito local.
Mapeo entre la Instancia de VueI18n y la Instancia de Composer
La API ofrecida por la instancia de Composer en la API de Composición es muy similar a la interfaz proporcionada por la instancia de VueI18n.
MEMO
Internamente, la instancia de VueI18n del modo de API heredado funciona envolviendo la instancia de Composer. Por esta razón, la sobrecarga de rendimiento es menor en el modo de API de Composición que en el modo de API heredado.
A continuación se muestra la tabla de mapeo:
| Instancia de VueI18n | Instancia de Composer |
|---|---|
id | id |
locale | locale |
fallbackLocale | fallbackLocale |
availableLocales | availableLocales |
messages | messages |
datetimeFormats | datetimeFormats |
numberFormats | numberFormats |
modifiers | modifiers |
missing | getMissingHandler / setMissingHandler |
postTranslation | getPostTranslationHandler / setPostTranslationHandler |
silentTranslationWarn | missingWarn |
silentFallbackWarn | fallbackWarn |
formatFallbackMessages | fallbackFormat |
sync | inheritLocale |
warnHtmlInMessage | warnHtmlMessage |
escapeParameterHtml | escapeParameter |
t | t |
tc | t |
te | te |
tm | tm |
getLocaleMessage | getLocaleMessage |
setLocaleMessage | setLocaleMessage |
mergeLocaleMessage | mergeLocaleMessage |
d | d |
getDateTimeFormat | getDateTimeFormat |
setDateTimeFormat | setDateTimeFormat |
mergeDateTimeFormat | mergeDateTimeFormat |
n | n |
getNumberFormat | getNumberFormat |
setNumberFormat | setNumberFormat |
mergeNumberFormat | mergeNumberFormat |