Разрывные изменения в v10
Включение JIT компиляции по умолчанию
Причина: Решены проблемы CSP и поддержка динамических ресурсов
JIT компиляция была представлена в v9.3. По умолчанию она не была включена.
Nuxt I18n, интегрирующий vue-i18n, уже имеет эту функцию включённой и стабильной по умолчанию. https://i18n.nuxtjs.org/docs/options/compilation#jit
Чтобы использовать эту функцию в Vue I18n, нам приходилось использовать сборщик и @intlify/unplugin-vue-i18n для активации флага __INTLIFY_JIT_COMPILATION__. По умолчанию в JIT компиляции этот флаг больше не нужен начиная с v10.
Если вы до сих пор не используете JIT компиляцию и собираетесь обновиться до v10 или новее, вам нужно будет пересобрать ваше приложение один раз.
О деталях JIT компиляции см. "Оптимизация".
Изменение сигнатуры перегрузки $t и t в режиме Legacy API
В Vue I18n v9 интерфейс $t и t в режиме Legacy API отличается от интерфейса в режиме Composition API.
В частности, сигнатура $t и t в режиме Legacy API имеет меньше перегрузок, чем в режиме Composition API, как показано ниже:
Перегрузки $t и t | Legacy API v9 | Legacy API v10 | Composition API 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; | - | ✅ | ✅ |
Начиная с v10, режим Legacy API может использовать ту же сигнатуру перегрузки $t и t, что и режим Composition API.
Причина: После этой миграции, при переходе к режиму Composition API, мы иногда попадаем в ловушку из-за различных сигнатур.
Если вы используете следующие API в режиме Legacy API, вы должны изменить сигнатуру из-за разрывных изменений:
$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 или новее:
используйте $t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult; или $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 или новее:
используйте $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 или новее:
используйте $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,
// какие-то опции ...
})
console.log(i18n.global.t('message.hello', 'ja'))Vue I18n v10 или новее:
используйте t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult; или t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
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,
// какие-то опции ...
})
console.log(i18n.global.t('message.hello', 'ja', ['dio']))Vue I18n v10 или новее:
используйте t(key: Key, list: unknown[], options: TranslateOptions): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
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,
// какие-то опции ...
})
console.log(i18n.global.t('message.hello', 'ja', { name: 'dio' }))Vue I18n v10 или новее:
используйте t(key: Key, named: NamedValue, options: TranslateOptions): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
console.log(i18n.global.t('message.hello', { name: 'dio' }, { locale: 'ja' }))Устаревшие tc и $tc в режиме Legacy API
Следующие API устарели в v10:
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;
Причина: Режим Legacy API уже имеет поддержку интерфейсов множественного числа в t и $t, поэтому их можно заменить.
В v10, tc и $tc всё ещё существуют, чтобы облегчить миграцию. Они будут полностью удалены в v11.
Если вы будете использовать их, Vue I18n выведет предупреждение в консоли вашего приложения.
tc(key: Key | ResourceKeys): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
console.log(i18n.global.tc('banana'))Vue I18n v10 или новее:
используйте t(key: Key | ResourceKeys, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
console.log(i18n.global.t('banana', 1))tc(key: Key | ResourceKeys, locale: Locales | Locale): TranslateResult;
Vue I18n v9.x:
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
console.log(i18n.global.tc('banana', 'ja'))Vue I18n v10 или новее:
используйте t(key: Key | ResourceKeys, plural: number, options: TranslateOptions<Locales>): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
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,
// какие-то опции ...
})
console.log(i18n.global.tc('banana', ['dio']))Vue I18n v10 или новее:
используйте t(key: Key | ResourceKeys, list: unknown[], plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
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,
// какие-то опции ...
})
console.log(i18n.global.tc('banana', { name: 'dio' }))Vue I18n v10 или новее:
используйте t(key: Key | ResourceKeys, named: NamedValue, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
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,
// какие-то опции ...
})
console.log(i18n.global.tc('banana', 2))Vue I18n v10 или новее:
используйте t(key: Key | ResourceKeys, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
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,
// какие-то опции ...
})
console.log(i18n.global.tc('banana', 2, 'ja'))Vue I18n v10 или новее:
используйте t(key: Key | ResourceKeys, plural: number, options: TranslateOptions<Locales>): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
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,
// какие-то опции ...
})
console.log(i18n.global.tc('banana', 2, ['dio']))Vue I18n v10 или новее:
используйте t(key: Key | ResourceKeys, list: unknown[], plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
console.log(i18n.global.t('banana', ['dio'], 2))tc(key: Key | ResourceKeys, choice: number, named: Record<string, unknown>): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
console.log(i18n.global.tc('banana', 2, { name: 'dio' }))Vue I18n v10 или новее:
используйте t(key: Key | ResourceKeys, named: NamedValue, plural: number): TranslateResult;
const i18n = createI18n({
legacy: true,
// какие-то опции ...
})
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 или новее:
используйте $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 или новее:
используйте $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 или новее:
используйте $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 или новее:
используйте $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 или новее:
используйте $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 или новее:
используйте $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 или новее:
используйте $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 или новее:
используйте $t(key: Key, named: NamedValue, plural: number): TranslateResult;
<template>
<p>{{ $t('banana', { name: 'dio' }, 2) }}</p>
</template>Удалена синтаксис модуля %
Именованная интерполяция с использованием модуля % больше не поддерживается в v10.
Причина: Синтаксис модуля был объявлен устаревшим в v9 с предупреждением.
Для миграции
Вы можете использовать eslint-plugin-vue-i18n.
eslint-plugin-vue-i18n имеет правило @intlify/vue-i18n/no-deprecated-modulo-syntax. https://eslint-plugin-vue-i18n.intlify.dev/rules/no-deprecated-modulo-syntax.html
Вы можете исправить с помощью eslint --fix
Перед обновлением до vue-i18n v10 вы должны выполнить миграцию с помощью eslint
Удалена vue-i18n-bridge
Причина: vue-i18n-bridge - это библиотека-мост для миграции vue-i18n с Vue 2 на Vue 3, а Vue 2 больше не находится в состоянии EOL.
Удалена опция allowComposition
Причина: Эта опция была объявлена устаревшей с предупреждением о её удалении в v10. Документация гласит: https://vue-i18n.intlify.dev/guide/migration/vue3.html#about-supporting
Эта опция была добавлена для поддержки миграции с Legacy API в Composition API в v9.
Удалена опция formatter в Legacy API
Причина: Эта опция была объявлена устаревшей с предупреждением в v9.
Удалена опция preserveDirectiveContent в Legacy API
Причина: Эта опция была объявлена устаревшей с предупреждением в v9.
Удалены модификаторы preserve в директиве v-t
Причина: Эта опция была объявлена устаревшей с предупреждением в v9.
Удалена getChoiceIndex в Legacy API
Причина: Эта опция была объявлена устаревшей с предупреждением в v9.
Удалена совместимость с компонентом перевода <i18n> v8.x
Причина: Эта опция была объявлена устаревшей с предупреждением в v9.
Удалена совместимость с поведением te v8.x
Причина: Эта опция была объявлена устаревшей с предупреждением в v9.
Эта опция была представлено в этом вопросе для поддержки поведения te v8.x в v9