Важные изменения в v9
Большинство API, предлагаемых в Vue I18n v9 (для Vue 3), стремятся сохранить совместимость, чтобы облегчить процесс миграции с v8 (для Vue 2). Однако при переходе вашего приложения всё же могут возникнуть некоторые важные изменения. Этот руководство показывает, как адаптировать ваше приложение для работы с Vue I18n v9.
API
new VueI18n становится createI18n
Vue I18n больше не является классом, а представляет собой набор функций. Вместо написания new VueI18n(), теперь вы должны вызвать createI18n:
Vue I18n v8.x:
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
const i18n = new VueI18n({
// ...
})
new Vue({
i18n,
// ...
})Vue I18n v9 или новее:
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
const i18n = createI18n({
// ...
})
const app = createApp({
// ...
})
app.use(i18n)Причина: Vue 3 Изменения глобального API и изменения архитектуры API Vue 3, связанные с экземплярами компонентов.
Переименование datetimeFormats из dateTimeFormats
Vue I18n v8.x:
const i18n = new VueI18n({
// ...
dateTimeFormats: {
// ...
}
})Vue I18n v9 или новее:
const i18n = createI18n({
// ...
datetimeFormats: {
// ...
}
})Значение, возвращаемое API перевода
API перевода, такое как $t и функция t, возвращают только строку. Объекты и массивы больше не возвращаются.
Vue I18n v8.x:
// Например, массив структурированных локализационных сообщений
const i18n = new VueI18n({
messages: {
en: {
errors: [
'invalid argument',
// ...
'unexpected errors'
]
}
}
})
// Например, компонент ошибки
const ErrorMessage = {
props: {
code: {
type: Number,
required: true
}
},
template: `<p class="error">{{ getErrorMessage(code) }}</p>`,
methods: {
getErrorMessage(code) {
return this.$t('errors')[code]
}
}
}В Vue I18n v9 и новее это изменилось: получение локализационных сообщений осуществляется через $tm / tm, а их разрешение — через $rt или rt. Пример с использованием Composition API:
// Например, массив структурированных локализационных сообщений
const i18n = createI18n({
messages: {
en: {
errors: [
'invalid argument',
// ...
'unexpected errors'
]
}
}
})
// Например, компонент ошибки
const ErrorMessage = {
props: {
code: {
type: Number,
required: true
}
},
template: `<p class="error">{{ errors(code) }}</p>`,
setup() {
const { tm, rt } = useI18n()
const errors = (code) => rt(tm('errors')[code])
return { errors }
}
}Причина: Для обеспечения простой обязательной возвратной модели результатов перевода, а также поддержки типов TypeScript.
Значение, возвращаемое API множественного числа
Аналогично Значению, возвращаемому API перевода, API множественного числа, такое как $tc и tc, возвращает только строку. Объекты и массивы больше не возвращаются.
Причина: Для обеспечения простой обязательной возвратной модели результатов перевода, а также поддержки типов TypeScript.
Удаление getChoiceIndex
CAUTION
Код реализации опции getChoiceIndex будет полностью удален в версии v10.
Чтобы кастомизировать правила множественного числа, Vue I18n v8.x расширяет getChoiceIndex класса VueI18n.
Vue I18n v8.x:
VueI18n.prototype.getChoiceIndex = function (choice, choicesLength) {
// this === экземпляр VueI18n, поэтому свойство locale существует
if (this.locale !== 'ru') {
// продолжить с реализацией по умолчанию
}
if (choice === 0) {
return 0;
}
const teen = choice > 10 && choice < 20;
const endsWithOne = choice % 10 === 1;
if (!teen && endsWithOne) {
return 1;
}
if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
return 2;
}
return (choicesLength < 4) ? 2 : 3;
}В Vue I18n v9 и новее вы можете кастомизировать это с помощью следующих опций:
Режим Legacy API:
import { createI18n } from 'vue-i18n'
function customRule(choice, choicesLength, orgRule) {
if (choice === 0) {
return 0
}
const teen = choice > 10 && choice < 20
const endsWithOne = choice % 10 === 1
if (!teen && endsWithOne) {
return 1
}
if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
return 2
}
return choicesLength < 4 ? 2 : 3
}
const i18n = createI18n({
// ...
pluralizationRules: {
ru: customRule,
// ...
},
// ...
})Режим Composition API:
import { useI18n } from 'vue-i18n'
function customRule(choice, choicesLength, orgRule) {
if (choice === 0) {
return 0
}
const teen = choice > 10 && choice < 20
const endsWithOne = choice % 10 === 1
if (!teen && endsWithOne) {
return 1
}
if (!teen && choice % 10 >= 2 && choice % 10 <= 4) {
return 2
}
return choicesLength < 4 ? 2 : 3
}
const MyComp = {
setup() {
const { t } = useI18n({
// ...
pluralRules: {
ru: customRule,
// ...
},
// ...
})
// ...
}
}Причина: Класс VueI18n был удален.
Изменение значения по умолчанию для опции warnHtmlInMessage
В Vue I18n v8.x значением warnHtmlInMessage было "off". Соответственно, предупреждения не выводятся в консоль даже если сообщение содержит HTML.
В Vue I18n v9 и новее изменены значения по умолчанию следующим образом:
- Режим Legacy API: свойство
warnHtmlInMessage:"warn" - Режим Composition API: булево свойство
warnHtmlMessage, по умолчаниюtrue
В режиме разработки, если вы не измените это значение, вы будете получать предупреждения в консоли по умолчанию.
В режиме продакшена проверка наличия HTML в сообщении не производится для максимальной производительности.
Причина: Для обеспечения более надежной безопасности локализационных сообщений
Информация о версии
Информация о версии теперь доступна через синтаксис импорта вместо статического свойства класса VueI18n.
Vue I18n v8.x:
import VueI18n from 'vue-i18n'
console.log(VueI18n.version)Vue I18n v9 или новее:
import { VERSION } from 'vue-i18n'
console.log(VERSION)Причина: Оптимизация tree shaking, а также класс VueI18n был удален.
Удаление доступности Intl
Удалено, так как основные браузеры теперь поддерживают ECMAScript Internationalization API.
Vue I18n v8.x:
import VueI18n from 'vue-i18n'
console.log(VueI18n.availability)Причина: Конец жизни IE9, а также класс VueI18n был удален.
Удаление пользовательского форматера
CAUTION
Код реализации опции formatter будет полностью удален в версии v10. В качестве альтернативы, vue-i18n имеет пользовательский формат сообщений как экспериментальную функцию.
Причина: Из-за сложности предоставления пользовательских форматов в новых API компилятора и времени выполнения. Мы планируем поддерживать эту возможность в следующем мажорном релизе для этих API. Если вы хотите использовать формат ICU сообщений, вы можете использовать @formatjs/vue-intl
Удаление опции preserveDirectiveContent
CAUTION
Код реализации опции preserveDirectiveContent будет полностью удален в версии v10.
Директива v-t для Vue 3 теперь сохраняет контент по умолчанию. Поэтому эта опция и её свойства были удалены из инстанса VueI18n.
Vue I18n v8.x:
import VueI18n from 'vue-i18n'
const i18n = new VueI18n({
// ...
preserveDirectiveContent: true,
// ...
})Причина: Сохранение содержимого элемента с директивой v-t
Синтаксис форматирования сообщений
Удаление массива как объекта для интерполяции списков
В Vue I18n v8.x интерполяция списков могла использовать массив как объект параметра, например:
import VueI18n from 'vue-i18n'
const i18n = new VueI18n({
// ...
messages: {
en: {
greeting: 'hello, {0}!'
}
},
// ...
})<p>{{ $t('greeting', { '0': 'kazupon' }) }}</p>В Vue I18n v9 и новее вы не можете использовать массивы как объекты для интерполяции списков, используйте массив:
<p>{{ $t('greeting', ['kazupon']) }}</p>Причина: Предоставление Translation API с согласованной сигнатурой аргументов
Обработка специальных символов
Сообщения, которые может переводить Vue I18n, могут быть высоко интерполированы с использованием синтаксиса форматирования сообщений, такого как:
@.caml:{'нет яблок'} | {0} яблоко | {n} яблокСинтаксис форматирования сообщений может использовать следующие специальные символы:
{,},@,$,|
Начиная с Vue I18n v9 и новее, синтаксис форматирования сообщений теперь обрабатывается компилятором форматирования сообщений. Если вы используете эти специальные символы как часть сообщения, это приведет к ошибке компиляции. Если вы хотите использовать эти специальные символы, вы должны использовать литеральную интерполяцию.
// Например, использование `@` для адреса электронной почты
{emailIdentity}{'@'}{emailDomain}Причина: Чтобы компилятор форматирования сообщений корректно обрабатывал специальные символы синтаксиса форматирования, необходимо ограничить их использование.
Удаление группировки скобок для связанных сообщений
В Vue I18n v8.x различали ссылки на ключи в связанных сообщениях и сообщения, использующие скобки (), чтобы отличать их друг от друга.
Vue I18n v8.x:
const messages = {
en: {
message: {
dio: 'DIO',
linked: 'Есть причина, ты проиграл, @:(message.dio).'
}
}
}В Vue I18n v9 и новее скобки больше не требуются, поскольку компилятор форматирования сообщений позволяет обрабатывать именные, списочные и буквальные интерполяции.
Vue I18n v9 или новее:
const messages = {
en: {
message: {
dio: 'DIO',
linked: "Есть причина, ты проиграл, @:{'message.dio'}."
}
}
}Директива v-t
Удаление модификатора preserve
CAUTION
Код реализации модификатора preserve будет полностью удален в версии v10.
Аналогично Удалению опции preserveDirectiveContent, директива v-t для Vue 3 теперь сохраняет контент по умолчанию. Поэтому модификатор preserve был удален из директивы v-t.
Vue I18n v8.x:
<p v-t.preserve="'hello'"></p>Причина: Сохранение содержимого элемента с директивой v-t
Компонент перевода
Переименование i18n-t из i18n
Имя тега компонента перевода (называемого функциональным компонентом i18n в Vue I18n v8.x) было изменено.
Vue I18n v8.x:
<i18n path="message.greeting" />Vue I18n v9 или новее:
<i18n-t keypath="message.greeting" />Причина: имя тега совпадает с блоками кастомных i18n <i18n>, что создает путаницу с именами блоков и подвержено ошибкам в SFC.
Свойство tag необязательное
В Vue I18n v8.x свойство tag можно было использовать для отображения дочерних элементов без корневого элемента, указав имя тега и булево значение false.
Vue I18n v8.x:
<i18n :tag="false" path="message.greeting">
<span>привет!</span>
</i18n>Начиная с Vue I18n v9 или новее, вы можете сделать то же самое, просто опустив свойство tag.
Vue I18n v9 или новее:
<i18n-t keypath="message.greeting">
<span>привет!</span>
</i18n-t>Причина: Теперь Vue 3 поддерживает фрагменты
Переименование свойства keypath из path
Vue I18n v8.x:
<i18n path="message.greeting" />Vue I18n v9 или новее:
<i18n-t keypath="message.greeting" />Удаление синтаксиса place с атрибутом place и свойством places
В Vue I18n v9 и новее атрибут place и свойство places были удалены из интерполяции компонентов.
Vue I18n v8.x:
<i18n path="info" tag="p" :places="{ limit: refundLimit }">
<span place="limit">{{ refundLimit }}</span>
<a place="action" :href="refundUrl">{{ $t('refund') }}</a>
</i18n>Vue I18n v9 или новее:
<i18n-t keypath="info" tag="p">
<template #limit>
<span>{{ refundLimit }}</span>
<template>
<template #action>
<a :href="refundUrl">{{ $t('refund') }}</a>
<template>
</i18n-t>Причина: Возможность сделать то же самое с помощью слотов
Компонент NumberFormat
Свойство tag необязательное
Аналогично разделу компонента перевода, в компоненте NumberFormat (называемом функциональным компонентом i18n-n в Vue I18n v8.x) свойство tag можно было использовать для отображения дочерних элементов без корневого элемента, указав имя тега и булево значение false.
Vue I18n v8.x:
<i18n-n :tag="false" :value="100" format="currency">
<span v-slot:integer="slotProps" styles="font-weight: bold">{{ slotProps.integer }}</span>
</i18n-n>Начиная с Vue I18n v9 или новее, вы можете сделать то же самое, просто опустив свойство tag.
Vue I18n v9 или новее:
<i18n-n :value="100" format="currency">
<span v-slot:integer="slotProps" styles="font-weight: bold">{{ slotProps.integer }}</span>
</i18n-n>Причина: Теперь Vue 3 поддерживает фрагменты