# Плюрализация

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

В шаблоне в таких случаях необходимо использовать метод $tc() вместо $t().

Сообщения локализации:

const messages = {
  en: {
    car: 'car | cars',
    apple: 'no apples | one apple | {count} apples'
  },
  ru: {
    car: 'машина | машины',
    apple: 'нет яблок | одно яблоко | {count} яблок'
  }
}

Шаблон:

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

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

Результат:

<p>машина</p>
<p>машины</p>

<p>нет яблок</p>
<p>одно яблоко</p>
<p>10 яблок</p>

# Аргумент для доступа к числу

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

Сообщения локализации:

const messages = {
  en: {
    apple: 'no apples | one apple | {count} apples',
    banana: 'no bananas | {n} banana | {n} bananas'
  },
  ru: {
    apple: 'нет яблок | одно яблоко | {count} яблок',
    banana: 'нет бананов | {n} банан | {n} бананов'
  }
}

Шаблон:

<p>{{ $tc('apple', 10, { count: 10 }) }}</p>
<p>{{ $tc('apple', 10) }}</p>

<p>{{ $tc('banana', 1, { n: 1 }) }}</p>
<p>{{ $tc('banana', 1) }}</p>
<p>{{ $tc('banana', 100, { n: 'слишком много' }) }}</p>

Результат:

<p>10 яблок</p>
<p>10 яблок</p>

<p>1 банан</p>
<p>1 банан</p>
<p>слишком много бананов</p>

# Пользовательская плюрализация

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

Можно предоставить собственную реализацию, передав pluralizationRules в конструктор VueI18n.

Упрощенный пример для славянских языков (Русский, Украинский и другие):

new VueI18n({
  // Ключ - язык, для которого будет применяться правило, в этом примере - `'ru'`
  // Value - функция плюрализации
  pluralizationRules: {
    /**
     * @param choice {number} индекс выбора, переданный в $tc: `$tc('path.to.rule', choiceIndex)`
     * @param choicesLength {number} общее количество доступных вариантов
     * @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 машин | {n} машина | {n} машины | {n} машин',
    banana: 'нет бананов | {n} банан | {n} банана | {n} бананов'
  }
}

Для такого формата вариантов 0 вещей | количество вещей заканчивается на 1 | количество вещей заканчивается на 2-4 | количество вещей заканчивается на 5-9, 0 и числа от 11 до 19. P.S. Славянское множественное число - сложное явление, подробнее о нем можно прочитать здесь (opens new window).

В шаблоне, по-прежнему, необходимо использовать $tc() вместо $t():

<p>{{ $tc('car', 1) }}</p>
<p>{{ $tc('car', 2) }}</p>
<p>{{ $tc('car', 4) }}</p>
<p>{{ $tc('car', 12) }}</p>
<p>{{ $tc('car', 21) }}</p>

<p>{{ $tc('banana', 0) }}</p>
<p>{{ $tc('banana', 4) }}</p>
<p>{{ $tc('banana', 11) }}</p>
<p>{{ $tc('banana', 31) }}</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>

# Плюрализация по умолчанию

Если для используемой локали не предоставить правило плюрализации, по умолчанию будет использовано правило для английского языка