Skip to content

Множественное число

Для локализации сообщений может потребоваться поддержка множественного числа для некоторых языков.

Vue i18n поддерживает множественное число, вы можете использовать API перевода с функцией множественного числа.

Основное использование

Вам нужно определить локализационные сообщения, которые имеют разделитель вертикальной черты |, и определить множественное число в разделителе вертикальной черты.

Локализационные сообщения ниже:

js
const messages = {
  en: {
    car: 'car | cars',
    apple: 'no apples | one apple | {count} apples'
  }
}

Здесь у нас есть объект локали en, который содержит car и apple.

Сообщение множественного числа для car имеет вид car | cars, а для apple - no apples | one apple | {count} apples.

Эти сообщения множественного числа выбираются по правилу выбора для каждого языка в API перевода согласно числовому значению, которое вы указываете в API перевода.

Vue I18n предлагает несколько способов поддержки множественного числа. Здесь мы будем использовать $t.

TIP

У $t есть некоторые перегрузки. О перегрузках см. Справочник по API

NOTE

Некоторые способы поддержки множественного числа:

  • глобальный $t, внедренный через инъекцию
  • встроенный компонент перевода (i18n-t)
  • экспортируемый t из useI18n (в режиме Composition API)

Ниже приведен пример использования API перевода.

html
<p>{{ $t('car', 1) }}</p>
<p>{{ $t('car', 2) }}</p>

<p>{{ $t('apple', 0) }}</p>
<p>{{ $t('apple', 1) }}</p>
<p>{{ $t('apple', 10, { count: 10 }) }}</p>

В приведенном выше примере использования $t первым аргументом является ключ локализационного сообщения, а вторым - число. $t возвращает выбранное сообщение в результате.

Результат ниже:

html
<p>car</p>
<p>cars</p>

<p>no apples</p>
<p>one apple</p>
<p>10 apples</p>

Предопределенные неявные аргументы

Не обязательно явно передавать число для множественного числа.

Посмотрим на пример, чтобы понять, что это значит!

Локализационные сообщения ниже:

js
const messages = {
  en: {
    apple: 'no apples | one apple | {count} apples',
    banana: 'no bananas | {n} banana | {n} bananas'
  }
}

Здесь у нас есть объект локали en, который содержит apple и banana.

Сообщение множественного числа для apple имеет вид no apples | one apple | {count} apples, а для banana - no bananas | {n} banana | {n} bananas.

Число может быть доступно внутри локализационных сообщений через предопределенные именованные аргументы {count} и/или {n}. При необходимости можно переопределять эти предопределенные именованные аргументы.

Ниже приведен пример использования $t:

html
<p>{{ $t('apple', 10, { named: { count: 10 } }) }}</p>
<p>{{ $t('apple', 10) }}</p>

<p>{{ $t('banana', 1, { named: { n: 1 } }) }}</p>
<p>{{ $t('banana', 1) }}</p>
<p>{{ $t('banana', 100, { named: { n: 'too many' } }) }}</p>

В приведенных выше примерах первый аргумент - ключ локализационного сообщения, второй - числовое значение или объект.

Если указан объект, это эквивалент интерполяции с именованными параметрами. Можно интерполировать n или count с неявными аргументами в сообщении множественного числа, передав их.

Результат ниже:

html
<p>10 apples</p>
<p>10 apples</p>

<p>1 banana</p>
<p>1 banana</p>
<p>too many bananas</p>

Пользовательское множественное число

Однако такое множественное число не применяется ко всем языкам (например, славянские языки имеют разные правила множественного числа).

Чтобы реализовать эти правила, вы можете передать необязательный объект pluralizationRules в опции конструктора VueI18n.

Очень упрощенный пример использования правил для славянских языков (русский, украинский и т. д.):

js
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
}

Чтобы использовать определенные выше пользовательские правила, внутри createI18n установите либо:

  1. pluralizationRules (для Options API) или
  2. pluralRules (для Composition API)

как в следующем примере:

js
const i18n = createI18n({
  locale: 'ru',
  // использовать pluralRules для Composition api
  pluralizationRules: {
    ru: customRule
  },
  messages: {
    ru: {
      car: '0 машин | {n} машина | {n} машины | {n} машин',
      banana: 'нет бананов | {n} банан | {n} банана | {n} бананов'
    }
  }
})

С использованием следующего шаблона:

html
<h2>Машина:</h2>
<p>{{ $t('car', 1) }}</p>
<p>{{ $t('car', 2) }}</p>
<p>{{ $t('car', 4) }}</p>
<p>{{ $t('car', 12) }}</p>
<p>{{ $t('car', 21) }}</p>

<h2>Банан:</h2>
<p>{{ $t('banana', 0) }}</p>
<p>{{ $t('banana', 4) }}</p>
<p>{{ $t('banana', 11) }}</p>
<p>{{ $t('banana', 31) }}</p>

Результат:

html
<h2>Машина:</h2>
<p>1 машина</p>
<p>2 машины</p>
<p>4 машины</p>
<p>12 машин</p>
<p>21 машина</p>

<h2>Банан:</h2>
<p>нет бананов</p>
<p>4 банана</p>
<p>11 бананов</p>
<p>31 банан</p>