# Введение
⚠️ Документация для Vue I18n v6.0 или более поздних версий. Если используете и ищете документацию для версии v5.x, обратитесь к разделу устаревшей версии.
Vue I18n — плагин для интернационализации во Vue.js. Он легко интегрирует дополнительные возможности по локализации приложения Vue.js.
Изучение лучше начинать с раздела Начало работы
# Спонсоры
# Золото

# Серебряные

# Бронза
# Поддержите на Patreon
Ваша компания для создания потрясающих приложений использует vue-i18n или vue-cli-plugin-i18n? Присоединяйтесь к другим патронам или становитесь спонсором, чтобы увидеть свой логотип в документации! Поддержка на Patreon позволяет автору меньше работать и больше заниматься развитием свободным опенсорсом, таким как vue-i18n! Спасибо!
Как работать с i18n в Nuxt.js

Сегодня хотел поделиться несколькими фишками в работе с i18n.
i18n – это фреймворк для интернализации веб-приложении. То есть, при помощи данного фреймворка мы легко можем реализовать мультиязычность в веб-приложениях.
Nuxt.js мощный инструмент для разработки веб-приложений. Помимо того, что он из коробки предоставляет много полезных утилит и инструментов, также, есть много дополнительных модулей из community, которые позволяют легко интегрировать разные инструменты в Nuxt.js. Посмотреть на сторонние модули для Nuxt.js можно здесь.
Nuxt i18n
Среди сторонних модулей, также есть модуль nuxt/i18n, который под капотом работает на vue-i18n. Данный модуль легко настраивается в Nuxt.js приложениях, достаточно просто в nuxt.config.js добавить модуль и настроить опции наиболее подходяще под проект:
Работа с переводами
После настройки модуля, можно уже работать непосредственно с переводами. Есть несколько способов работы с переводами. Вынести переводы в отдельные файлы, и хранить их там, хранить переводы непосредственно в nuxt.config.js (не рекомендуется), и хранить переводы в самих компонентах.
Как лучше хранить переводы
Если речь идет о переводах в виде названий кнопок, разных плашек и других переводов, которые используются в абстрактных компонентах, в атомах или молекулах при атомарном дизайне, то можно хранить подобные переводы в самих компонентах, так как они обычны лишены контекста:
Подробнее о подобном подходе хранения переводов можно ознакомиться тут.
А вот если речь идет уже о словах или фразах, которые имеют какой-то контекст к проекту, которые часто встречаются в компонентах, то их желательно хранить как TypeScript или JSON файл в директорий src/i18n
export const ru = < common: < all: 'все', >, partners: 'Организаторы | Партнеры | Организаторы и партнеры', page_names: < home: 'Главная | На главную', contests: 'Конкурсы | Конкурс', events: 'Мероприятия | Мероприятие', faq: 'Вопросы и ответы', live_tournaments: 'Live турниры', rating: 'Рейтинг', shop: 'Магазин', streams: 'Стримы | Стрим', tournaments: 'Турниры | Турнир', >, . >
Множественность в переводах
i18n позволяет хранить в одном ключе несколько вариации перевода, в том числе и множественности. К примеру, у нас есть слово “Конкурсы”, однако в некоторых местах у нас это же слово в единственном числе “Конкурс”. Хранить это в двух разных ключах неудобно и не эффективно. Поэтому для этого надо хранить данный ключ можно следующем образом:
export const ru =
А уже в компонентах, чтоб использовать данный перевод надо обращаться к методу $tc вместо $t :
> // на выходе будет 'Конкурсы' > // на выходе будет 'Конкурс'
Данный функционал также можно использовать для слов синонимов, которые встречаются в проекте:
export const ru =
Переиспользование ключей переводов
i18n также позволяет переиспользовать существующие ключи переводов и объединять их вместе:
export const ru = < day: 'день', is_weekend: 'выходной', weekend: '@:day @:is_weekend', // 'выходной день' >
Интерполяция переводов
Бывают ситуации, когда надо интерполировать переводы. К примеру, мне надо выводить подобные текста:
- с 24.02.2022 до 25.02.2022
- 24.02.2022 бастап 25.02.2022 дейін
- from 24.02.2022 to 25.02.22
Дату я получаю с сервера, и дата должна быть обернута в HTML тег . А на разных языках я имею разный шаблон перевода. Для этого можно использовать интерполяцию в i18n:
export const ru = < date_range: 'с до ' > export const kk = < date_range: 'бастап дейін' > export const en = < date_range: 'from to ' >
В данном случае получается, что наши данные, которые мы хотим интерполировать мы прописываем в метках, как / .
В итоге, в нашем компоненте, в шаблоне мы это прописываем следующим образом:
Подробнее об интерполяции можно почитать в документации здесь.
Очень сильно рекомендую вам ознакомиться и изучить документации модуля под Nuxt.js и самого Vue-i18n. Так как там описано много, и о многих утилитах в работе с этим инструментом:
- Документация nuxt/i18n
- Документация vue-i18n
# Плюрализация
Для переводимых сообщений есть возможность использовать плюрализацию. Для этого необходимо указывать строки переводов для различных случаев через разделитель | .
В шаблоне в таких случаях необходимо использовать метод $tc() вместо $t() .
const messages = en: car: 'car | cars', apple: 'no apples | one apple | apples' >, ru: car: 'машина | машины', apple: 'нет яблок | одно яблоко | яблок' > >
p>>p> p>>p> p>>p> p>>p> p>) >>p>
p>машинаp> p>машиныp> p>нет яблокp> p>одно яблокоp> p>10 яблокp>
# Аргумент для доступа к числу
Нет необходимости явно передавать число для плюрализации. В сообщениях локализации число доступно через именованные аргументы и/или . При желании их можно переопределить.
const messages = en: apple: 'no apples | one apple | apples', banana: 'no bananas | banana | bananas' >, ru: apple: 'нет яблок | одно яблоко | яблок', banana: 'нет бананов | банан | бананов' > >
p>) >>p> p>>p> p>) >>p> p>>p> p>) >>p>
p>10 яблокp> p>10 яблокp> p>1 бананp> p>1 бананp> p>слишком много банановp>
# Пользовательская плюрализация
Стандартная реализация плюрализации не подходит для некоторых языков (к примеру, в славянских языках другие правила множественности).
Можно предоставить собственную реализацию, передав pluralizationRules в конструктор VueI18n .
Упрощенный пример для славянских языков (Русский, Украинский и другие):
new VueI18n( // Ключ - язык, для которого будет применяться правило, в этом примере - `'ru'` // Value - функция плюрализации pluralizationRules: /** * @param choice индекс выбора, переданный в $tc: `$tc('path.to.rule', choiceIndex)` * @param choicesLength общее количество доступных вариантов * @returns финальный индекс для выбора соответственного варианта слова */ 'ru': function(choice, choicesLength) // this === VueI18n экземпляра, так что свойство locale также существует здесь if (choice === 0) return 0; > const teen = choice > 10 && choice 20; const endsWithOne = choice % 10 === 1; if (choicesLength 4) return (!teen && endsWithOne) ? 1 : 2; > if (!teen && endsWithOne) return 1; > if (!teen && choice % 10 >= 2 && choice % 10 4) return 2; > return (choicesLength 4) ? 2 : 3; > > >)
Такая реализация позволит использовать:
const messages = ru: car: '0 машин | машина | машины | машин', banana: 'нет бананов | банан | банана | бананов' > >
Для такого формата вариантов 0 вещей | количество вещей заканчивается на 1 | количество вещей заканчивается на 2-4 | количество вещей заканчивается на 5-9, 0 и числа от 11 до 19 . P.S. Славянское множественное число — сложное явление, подробнее о нем можно прочитать здесь
В шаблоне, по-прежнему, необходимо использовать $tc() вместо $t() :
p>>p> p>>p> p>>p> p>>p> p>>p> p>>p> p>>p> p>>p> p>>p>
p>1 машинаp> p>2 машиныp> p>4 машиныp> p>12 машинp> p>21 машинаp> p>нет банановp> p>4 бананаp> p>11 банановp> p>31 бананp>
# Плюрализация по умолчанию
Если для используемой локали не предоставить правило плюрализации, по умолчанию будет использовано правило для английского языка
# Пользовательская директива
Переводы можно осуществлять не только используя пользовательскую директиву v-t , но и с помощью метода $t .
# Строковый синтаксис
Можно передавать ключ сообщения локализации строкой.
new Vue( i18n: new VueI18n( locale: 'en', messages: en: hello: 'hi there!' >, ru: hello: 'привет всем!' > > >), data: path: 'hello' > >).$mount('#string-syntax')
div id="string-syntax"> p v-t="'hello'">p> p v-t="path">p> div>
div id="string-syntax"> p>привет всем!p> p>привет всем!p> div>
# Объектный синтаксис
Можно использовать объектный синтаксис.
new Vue( i18n: new VueI18n( locale: 'en', messages: en: hello: 'hi !' >, ru: hello: 'привет !' > > >), computed: nickName() return 'kazupon' > >, data: path: 'hello' > >).$mount('#object-syntax')
div id="object-syntax"> p v-t="< path: 'hello', locale: 'ru', args: < name: 'kazupon' > >">p> p v-t=" < path: path, args: < name: nickName >>">p> div>
div id="object-syntax"> p>привет、kazupon!p> p>hi kazupon!p> div>
# Использование с transition
Поддержка с версии
При использовании директивы v-t на элементе внутри компонента
(opens new window) , можно заметить как переведённое сообщение исчезает во время анимации перехода. Это поведение связано с реализацией самого компонента — все директивы в исчезающем элементе внутри компонента должны быть уничтожены до начала анимации. Это может привести к мерцанию содержимого на коротких анимациях, но наиболее заметно при длинных анимациях переходов.
Чтобы сохранить содержимое директивы во время анимации перехода, необходимо добавить модификатор .preserve при определении директивы v-t .
new Vue( i18n: new VueI18n( locale: 'en', messages: en: preserve: 'with preserve' > > >), data: toggle: true > >).$mount('#in-transitions')
div id="in-transitions"> transition name="fade"> span v-if="toggle" v-t.preserve="'preserve'">span> transition> button @click="toggle = !toggle">Togglebutton> div>
Также можно глобально установить настройку preserveDirectiveContent в экземпляре VueI18n , что повлияет на все директивы v-t без добавления модификатора к ним.
new Vue( i18n: new VueI18n( locale: 'en', messages: en: preserve: 'with preserve' > >, preserveDirectiveContent: true >), data: toggle: true > >).$mount('#in-transitions')
div id="in-transitions"> transition name="fade"> span v-if="toggle" v-t="'preserve'">span> transition> button @click="toggle = !toggle">Togglebutton> div>
Подробнее о примерах выше можно изучить здесь
# $t или v-t
# $t
$t — это метод, добавленный в экземпляр Vue. У него следующие плюсы и минусы:
# Плюсы
Предоставляет гибкость в использовании синтаксиса фигурных скобок > в шаблонах, а также применять в вычисляемых свойствах и методах экземпляра Vue.
# Минусы
$t выполняется каждый раз когда происходит перерисовка, поэтому у него есть расходы на осуществление перевода.
# v-t
v-t — пользовательская директива. У неё следующие плюсы и минусы:
# Плюсы
v-t имеет лучшую производительность в сравнении с методом $t , благодаря кэшу в пользовательской директиве после выполнения перевода. Также можно реализовать предварительный перевод с помощью модуля для компилятора Vue, который предоставляет плагин vue-i18n-extensions
Таким образом, можно достичь большей оптимизации производительности.
# Минусы
v-t нельзя использовать также гибко, как $t , и это добавляет сложности. Перевод с помощью v-t вставляется в textContent элемента. Также, при использовании рендеринга на стороне сервера необходимо установить пользовательскую директиву
(opens new window) через опцию directives функции createRenderer .