Cambios importantes en la versión 10
Habilitación por defecto para la compilación JIT
Motivo: Se pueden resolver problemas de CSP y se pueden admitir recursos dinámicos.
La compilación JIT fue introducida en la versión 9.3. No estaba habilitada por defecto.
Nuxt I18n, que integra vue-i18n, ya tiene esta función habilitada y estable por defecto. https://i18n.nuxtjs.org/docs/options/compilation#jit
Para usar esta característica en Vue I18n, teníamos que utilizar un empaquetador y @intlify/unplugin-vue-i18n para activar la bandera __INTLIFY_JIT_COMPILATION__. Por defecto en la compilación JIT, esta bandera ya no es necesaria a partir de la versión 10.
Si aún no estás utilizando la compilación JIT y planeas actualizar a la versión 10 o posterior, necesitarás reconstruir tu aplicación una vez.
Para detalles sobre la compilación JIT, consulta "Optimización".
Cambio en las firmas sobrecargadas de $t y t para el modo de API heredado
En Vue I18n v9, tiene una interfaz diferente del modo de API de composición y del modo de API heredado para las firmas sobrecargadas de $t y t.
Especialmente, la firma de $t y t en el modo de API heredado tiene menos firmas sobrecargadas que en el modo de API de composición, como se muestra a continuación:
Firmas sobrecargadas de $t y t | API heredada v9 | API heredada v10 | API de composición v9 & v10 |
|---|---|---|---|
$t(key: Key): TranslateResult; | ✅ | ✅ | ✅ |
$t(key: Key, locale: Locale): TranslateResult; | ✅ | - | - |
$t(key: Key, locale: Locale, list: unknown[]): TranslateResult; | ✅ | - | - |
$t(key: Key, locale: Locale, named: NamedValue): TranslateResult; | ✅ | - | - |
$t(key: Key, plural: number): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, plural: number, options: TranslateOptions): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, defaultMsg: string, options: TranslateOptions): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, list: unknown[]): TranslateResult; | ✅ | ✅ | ✅ |
$t(key: Key, list: unknown[], plural: number): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, list: unknown[], defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, named: Record<string, unknown>): TranslateResult; | ✅ | ✅ | ✅ |
$t(key: Key, named: NamedValue, plural: number): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, named: NamedValue, defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
$t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult; | - | ✅ | ✅ |
t(key: Key): TranslateResult; | ✅ | ✅ | ✅ |
t(key: Key, locale: Locale): TranslateResult; | ✅ | - | - |
t(key: Key, locale: Locale, list: unknown[]): TranslateResult; | ✅ | - | - |
t(key: Key, locale: Locale, named: Record<string, unknown>): TranslateResult; | ✅ | - | - |
t(key: Key, plural: number): TranslateResult; | - | ✅ | ✅ |
t(key: Key, plural: number, options: TranslateOptions<Locales>): TranslateResult; | - | ✅ | ✅ |
t(key: Key, defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
t(key: Key, defaultMsg: string, options: TranslateOptions<Locales>): TranslateResult; | - | ✅ | ✅ |
t(key: Key, list: unknown[]): TranslateResult; | ✅ | ✅ | ✅ |
t(key: Key, list: unknown[], plural: number): TranslateResult; | - | ✅ | ✅ |
t(key: Key, list: unknown[], defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
t(key: Key, list: unknown[], options: TranslateOptions<Locales>): TranslateResult; | - | ✅ | ✅ |
t(key: Key, named: Record<string, unknown>): TranslateResult; | ✅ | ✅ | ✅ |
t(key: Key, named: NamedValue, plural: number): TranslateResult; | - | ✅ | ✅ |
t(key: Key, named: NamedValue, defaultMsg: string): TranslateResult; | - | ✅ | ✅ |
t(key: Key, named: NamedValue, options: TranslateOptions<Locales>): TranslateResult; | - | ✅ | ✅ |
A partir de la versión 10, el modo de API heredado puede usar las mismas firmas sobrecargadas de $t y t que el modo de API de composición.
Motivo: Tras esa migración, al migrar al modo de API de composición, a veces caemos en una trampa debido a la diferencia de firma.
Si estás usando las siguientes APIs en el modo de API heredado, debes cambiar a otra firma debido a los cambios importantes:
$t(key: Key, locale: Locale): TranslateResult;$t(key: Key, locale: Locale, list: unknown[]): TranslateResult;$t(key: Key, locale: Locale, named: NamedValue): TranslateResult;t(key: Key, locale: Locale): TranslateResult;t(key: Key, locale: Locale, list: unknown[]): TranslateResult;t(key: Key, locale: Locale, named: NamedValue): TranslateResult;
$t(key: Key, locale: Locale): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $t('message.hello', 'ja') }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult; o $t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult;
<template>
<p>{{ $t('message.hello', {}, { locale: 'ja' }) }}</p>
</template>$t(key: Key, locale: Locale, list: unknown[]): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $t('message.hello', 'ja', ['dio']) }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult;
<template>
<p>{{ $t('message.hello', ['dio'], { locale: 'ja' }) }}</p>
</template>$t(key: Key, locale: Locale, named: NamedValue): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $t('message.hello', 'ja', { name: 'dio' }) }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult;
<template>
<p>{{ $t('message.hello', { name: 'dio' }, { locale: 'ja' }) }}</p>
</template>t(key: Key, locale: Locale): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('message.hello', 'ja'))Vue I18n v10 o posterior:
usa t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult; o t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('message.hello', {}, { locale: 'ja' }))t(key: Key, locale: Locale, list: unknown[]): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('message.hello', 'ja', ['dio']))Vue I18n v10 o posterior:
usa t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('message.hello', ['dio'], { locale: 'ja' }))t(key: Key, locale: Locale, named: NamedValue): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('message.hello', 'ja', { name: 'dio' }))Vue I18n v10 o posterior:
usa t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('message.hello', { name: 'dio' }, { locale: 'ja' }))Descontinuación de tc y $tc para el modo de API heredado
Las siguientes APIs están descontinuadas en la versión 10:
tc(key: Key | ResourceKeys): TranslateResult;tc(key: Key | ResourceKeys, locale: Locales | Locale): TranslateResult;tc(key: Key | ResourceKeys, list: unknown[]): TranslateResult;tc(key: Key | ResourceKeys, named: Record<string, unknown>): TranslateResult;tc(key: Key | ResourceKeys, choice: number): TranslateResult;tc(key: Key | ResourceKeys, choice: number, locale: Locales | Locale): TranslateResult;tc(key: Key | ResourceKeys, choice: number, list: unknown[]): TranslateResult;tc(key: Key | ResourceKeys, choice: number, named: Record<string, unknown>): TranslateResult;$tc(key: Key): TranslateResult;$tc(key: Key, locale: Locale): TranslateResult;$tc(key: Key, list: unknown[]): TranslateResult;$tc(key: Key, named: Record<string, unknown>): TranslateResult;$tc(key: Key, choice: number): TranslateResult;$tc(key: Key, choice: number, locale: Locale): TranslateResult;$tc(key: Key, choice: number, list: unknown[]): TranslateResult;$tc(key: Key, choice: number, named: Record<string, unknown>): TranslateResult;
Motivo: El modo de API heredado tiene soporte para interfaces plurales en t y $t, por lo tanto, pueden ser reemplazados.
En la versión 10, tc y $tc todavía existen para facilitar la migración. Estas se eliminarán completamente en la versión 11.
Si las usas, Vue I18n emitirá una advertencia en la consola de tu aplicación.
tc(key: Key | ResourceKeys): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.tc('banana'))Vue I18n v10 o posterior:
usa t(key: Key | ResourceKeys, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('banana', 1))tc(key: Key | ResourceKeys, locale: Locales | Locale): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.tc('banana', 'ja'))Vue I18n v10 o posterior:
usa t(key: Key | ResourceKeys, plural: number, options: TranslateOptions<Locales>): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('banana', 1, { locale: 'ja' }))tc(key: Key | ResourceKeys, list: unknown[]): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.tc('banana', ['dio']))Vue I18n v10 o posterior:
usa t(key: Key | ResourceKeys, list: unknown[], plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('banana', ['dio'], 1))tc(key: Key | ResourceKeys, named: Record<string, unknown>): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.tc('banana', { name: 'dio' }))Vue I18n v10 o posterior:
usa t(key: Key | ResourceKeys, named: NamedValue, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('banana', { name: 'dio' }, 1))tc(key: Key | ResourceKeys, choice: number): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.tc('banana', 2))Vue I18n v10 o posterior:
usa t(key: Key | ResourceKeys, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('banana', 2))tc(key: Key | ResourceKeys, choice: number, locale: Locales | Locale): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.tc('banana', 2, 'ja'))Vue I18n v10 o posterior:
usa t(key: Key | ResourceKeys, plural: number, options: TranslateOptions<Locales>): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('banana', 2, { locale: 'ja' }))tc(key: Key | ResourceKeys, choice: number, list: unknown[]): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.tc('banana', 2, ['dio']))Vue I18n v10 o posterior:
usa t(key: Key | ResourceKeys, list: unknown[], plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('banana', ['dio'], 2))tc(key: Key | ResourceKeys, choice: number, named: Record<string, unknown>): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.tc('banana', 2, { name: 'dio' }))Vue I18n v10 o posterior:
usa t(key: Key | ResourceKeys, named: NamedValue, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// algunas opciones...
})
console.log(i18n.global.t('banana', { name: 'dio' }, 2))$tc(key: Key): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana') }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, plural: number): TranslateResult;
<template>
<p>{{ $t('banana', 1) }}</p>
</template>$tc(key: Key, locale: Locale): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', 'ja') }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, plural: number, options: TranslateOptions): TranslateResult;
<template>
<p>{{ $t('banana', 1, { locale: 'ja' }) }}</p>
</template>$tc(key: Key, list: unknown[]): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', ['dio']) }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, list: unknown[], plural: number): TranslateResult;
<template>
<p>{{ $t('banana', ['dio'], 1) }}</p>
</template>$tc(key: Key, named: Record<string, unknown>): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', { name: 'dio' }) }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, named: NamedValue, plural: number): TranslateResult;
<template>
<p>{{ $t('banana', { name: 'dio' }, 1) }}</p>
</template>$tc(key: Key, choice: number): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', 2) }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, plural: number): TranslateResult;
<template>
<p>{{ $t('banana', 2) }}</p>
</template>$tc(key: Key, choice: number, locale: Locale): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', 2, 'ja') }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, plural: number, options: TranslateOptions): TranslateResult;
<template>
<p>{{ $t('banana', 2, { locale: 'ja' }) }}</p>
</template>$tc(key: Key, choice: number, list: unknown[]): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', 2, ['dio']) }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, list: unknown[], plural: number): TranslateResult;
<template>
<p>{{ $t('banana', ['dio'], 2) }}</p>
</template>$tc(key: Key, choice: number, named: Record<string, unknown>): TranslateResult;
Vue I18n v9.x:
<template>
<p>{{ $tc('banana', 2, { name: 'dio' }) }}</p>
</template>Vue I18n v10 o posterior:
usa $t(key: Key, named: NamedValue, plural: number): TranslateResult;
<template>
<p>{{ $t('banana', { name: 'dio' }, 2) }}</p>
</template>Eliminación de la sintaxis % de módulo
La interpolación con nombre usando el operador de módulo % ya no es compatible en la versión 10.
Motivo: La sintaxis de módulo ya había sido descontinuada en la versión 9 con una advertencia.
Para migrar
Puedes usar eslint-plugin-vue-i18n.
eslint-plugin-vue-i18n tiene la regla @intlify/vue-i18n/no-deprecated-modulo-syntax. https://eslint-plugin-vue-i18n.intlify.dev/rules/no-deprecated-modulo-syntax.html
Puedes corregir usando eslint --fix
Debes haber migrado con eslint antes de actualizar a vue-i18n v10
Eliminación de vue-i18n-bridge
Motivo: vue-i18n-bridge es una biblioteca puente para migrar vue-i18n desde Vue 2 hasta Vue 3, y Vue 2 ya no está más fuera de su ciclo de vida (EOL).
Eliminación de la opción allowComposition
Motivo: Esta opción ya fue descontinuada con una advertencia sobre que sería eliminada en la versión 10. Los documentos indican: https://vue-i18n.intlify.dev/guide/migration/vue3.html#about-supporting
Esta opción fue añadida para apoyar la migración del API heredado al API de composición en la versión 9.
Eliminación de la opción formatter en el API heredado
Motivo: Esta opción fue descontinuada con una advertencia en la versión 9.
Eliminación de la opción preserveDirectiveContent en el API heredado
Motivo: Esta opción fue descontinuada con una advertencia en la versión 9.
Eliminación de códigos de modificador preserve en la directiva v-t
Motivo: Esta opción fue descontinuada con una advertencia en la versión 9.
Eliminación de getChoiceIndex en el API heredado
Motivo: Esta opción fue descontinuada con una advertencia en la versión 9.
Eliminación de compatibilidad con el componente de traducción <i18n> de la versión 8.x
Motivo: Esta opción fue descontinuada con una advertencia en la versión 9.
Eliminación del comportamiento te de compatibilidad con la versión 8.x
Motivo: Esta opción fue descontinuada con una advertencia en la versión 9.
Esta opción fue introducida en este problema para apoyar la compatibilidad con el comportamiento de te de la versión 8.x en la versión 9