Composition API
Введение setup и Composition API Vue открывает новые возможности. Однако для получения максимальной эффективности от Vue I18n нам нужно будет использовать несколько новых функций для замены доступа к this.
Мы описывали возможности Vue I18n, используя Legacy API, который совместим с vue-i18n v8.x. Теперь давайте рассмотрим useI18n Vue I18n для Composition API.
Основное использование
Давайте рассмотрим основное использование Composition API Vue I18n! Здесь мы изучим базовое использование, изменяя код в Начало работы для освоения основ.
Чтобы использовать useI18n в setup Vue 3, есть одна вещь, которую нужно сделать: установите опцию legacy функции createI18n в false.
Следующий пример показывает добавление опции legacy к createI18n:
// ...
const i18n = VueI18n.createI18n({
legacy: false, // вы должны установить `false`, чтобы использовать Composition API
locale: 'ja',
fallbackLocale: 'en',
messages: {
en: {
message: {
hello: 'hello world'
}
},
ja: {
message: {
hello: 'こんにちは、世界'
}
}
}
})
// ...Вы можете установить legacy: false, чтобы позволить Vue I18n переключиться в режим API, с Legacy API mode на Composition API mode.
ПРИМЕЧАНИЕ
Следующие свойства экземпляра i18n, созданного createI18n, изменяют его поведение:
- Свойство
mode:"legacy"на"composition" - Свойство
global: экземпляр VueI18n на экземпляр Composer
Теперь вы готовы использовать useI18n в компоненте App.vue. Код выглядит так:
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script> // [!code ++]
<template>
<h1>{{ $t("message.hello") }}</h1>
</template>Вы должны вызвать useI18n в начале <script setup>.
The useI18n возвращает экземпляр Composer. Экземпляр Composer предоставляет API перевода, такой как функция t, а также свойства, такие как locale и fallbackLocale, точно так же, как и экземпляр VueI18n. За дополнительной информацией об экземпляре Composer см. Справочник по API.
В приведенном выше примере нет параметров для useI18n, поэтому он возвращает экземпляр Composer, работающий в глобальной области видимости. Таким образом, он возвращает экземпляр Composer, работающий в глобальной области видимости, что означает, что локализованное сообщение, на которое ссылается функция t, указано в createI18n.
Вы можете использовать t в шаблоне компонентов:
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
</script>
<template>
<h1>{{ $t("message.hello") }}</h1> // [!code --]
<h1>{{ t("message.hello") }}</h1> // [!code ++]
</template>Результат следующий:
<div id="app">
<h1>こんにちは、世界</h1>
</div>Перевод сообщений
В режиме Legacy API сообщения переводились с использованием $t или экземпляра VueI18n t.
В режиме Composition API синтаксис форматирования сообщений остается таким же, как и в режиме Legacy API. Вы можете использовать t экземпляра Composer для перевода сообщения следующим образом:
<script setup>
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n({
locale: 'en',
messages: {
en: {
msg: 'hello',
named: '{msg} world!',
list: '{0} world!',
literal: "{'hello'} world!",
the_world: 'the world',
dio: 'DIO:',
linked: '@:dio @:the_world !!!!'
},
ja: {
msg: 'こんにちは',
named: '{msg} 世界!',
list: '{0} 世界!',
literal: "{'こんにちは'} 世界!",
the_world: 'ザ・ワールド!',
dio: 'ディオ:',
linked: '@:dio @:the_world !!!!'
}
}
})
const msg = computed(() => t('msg'))
</script>
<template>
<p>{{ t('named', { msg }) }}</p>
<p>{{ t('list', [msg]) }}</p>
<p>{{ t('literal') }}</p>
<p>{{ t('linked') }}</p>
</template>За дополнительными сведениями о t см. Справочник по API
Множественное число
В режиме Composition API форма множественного числа сообщения остается такой же, как и в режиме Legacy API, но перевод осуществляется с помощью t экземпляра Composer:
<script setup>
import { useI18n } from 'vue-i18n'
const { t } = useI18n({
locale: 'en',
messages: {
en: {
car: 'car | cars',
apple: 'no apples | one apple | {count} apples',
banana: 'no bananas | {n} banana | {n} bananas'
}
}
})
</script>
<template>
<h2>Car:</h2>
<p>{{ t('car', 1) }}</p>
<p>{{ t('car', 2) }}</p>
<h2>Apple:</h2>
<p>{{ t('apple', 0) }}</p>
<p>{{ t('apple', 1) }}</p>
<p>{{ t('apple', { count: 10 }, 10) }}</p>
<p>{{ t('apple', 10) }}</p>
<h2>Banana:</h2>
<p>{{ t('banana', { n: 1 }, 1) }}</p>
<p>{{ t('banana', 1) }}</p>
<p>{{ t('banana', { n: 'too many' }, 100) }}</p>
</template>ПРИМЕЧАНИЕ
В режиме Composition API переводы множественного числа были интегрированы в t.
Форматирование даты и времени
В режиме Legacy API значение даты и времени форматировалось с использованием $d или экземпляра VueI18n d.
В режиме Composition API используется d экземпляра Composer для форматирования:
<script setup>
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
const { t, d } = useI18n({
locale: 'en-US',
messages: {
'en-US': {
current: 'Current Datetime'
}
},
datetimeFormats: {
'en-US': {
long: {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
}
}
}
})
const now = ref(new Date())
</script>
<template>
<p>{{ t('current') }}: {{ d(now, 'long') }}</p>
</template>За дополнительными сведениями о d см. Справочник по API
Форматирование чисел
В режиме Legacy API числовые значения форматировались с использованием $n или n экземпляра VueI18n.
В режиме Composition API форматирование осуществляется с помощью n экземпляра Composer:
<script setup>
import { ref } from 'vue'
import { useI18n } from 'vue-i18n'
const { t, n } = useI18n({
locale: 'en-US',
messages: {
'en-US': {
money: 'Money'
}
},
numberFormats: {
'en-US': {
currency: {
style: 'currency',
currency: 'USD'
}
}
}
})
const money = ref(1000)
</script>
<template>
<p>{{ t('money') }}: {{ n(money, 'currency') }}</p>
</template>За дополнительными сведениями о n см. Справочник по API
Глобальная область видимости
Глобальная область видимости в режиме Composition API создается при создании экземпляра i18n с помощью createI18n, аналогично режиму Legacy API.
Хотя свойство global в режиме Legacy API экземпляра i18n является экземпляром VueI18n, в режиме Composition API вы можете ссылаться на экземпляр Composer.
Существует два способа ссылки на экземпляр Composer глобальной области видимости в компоненте.
Явно с помощью useI18n
Как мы объяснили, в useI18n есть один способ.
import { useI18n } from 'vue-i18n'
const { t } = useI18n({ useScope: 'global' })
// Что-то делаем здесь ...Приведенный выше код устанавливает опцию useI18n в useScope: 'global', что позволяет useI18n вернуть экземпляр Composer, который может быть доступен через свойство global экземпляра i18n. Экземпляр Composer находится в глобальной области видимости.
Затем вы можете использовать функции и свойства, предоставленные экземпляром Composer.
ПРИМЕЧАНИЕ
Если вы установите useI18n с messages, datetimeFormats и numberFormats вместе с useScope: 'global', они будут объединены в глобальную область видимости. То есть они будут управляться messages, datetimeFormasts и numberFormats экземпляра Composer глобальной области видимости.
И также, если global указан в пользовательских блоках i18n (например, <i18n global>{ … }</i18n>), локализованные сообщения, определенные в блоках, объединяются с глобальной областью видимости.
Неявно с помощью внедренных свойств и функций
Другой способ ссылки на экземпляр Composer глобальной области видимости — через свойства и функции, неявно внедренные в компонент.
Вам нужно указать globalInjection: true вместе с legacy: false как опцию для createI18n, поскольку по умолчанию она отключена.
ПРИМЕЧАНИЕ
vue-i18n v9.2-beta.34 или новее, globalInjection по умолчанию равен true.
Это позволяет Vue I18n внедрить следующие свойства и функции в компоненты:
$i18n: объект, обернутый свойствами экземпляра Composer глобальной области видимостиlocalefallbackLocaleavailableLocales
$t: функцияtэкземпляра Composer глобальной области видимости$rt: функцияrtэкземпляра Composer глобальной области видимости$d: функцияdэкземпляра Composer глобальной области видимости$n: функцияnэкземпляра Composer глобальной области видимости$tm: функцияtmэкземпляра Composer глобальной области видимости
Vue 3 runtime глобально внедряет компоненты с тем, что установлено в app.config.globalProperties. Таким образом, перечисленные выше внедряются с помощью runtime Vue 3 и могут быть использованы неявно в шаблонах.
УВЕДОМЛЕНИЕ
- В
setupнельзя увидеть эти свойства и функции, внедренные в компонент - В режиме Legacy API некоторые API Vue I18n с префиксом
$были внедрены, но свойства и функции, внедренные в компоненты с префиксом$в режиме Composition API, отличаются от режима Legacy API.
Вы заметили, что выше перечисленные элементы имеют префикс $. Причина использования префикса $ заключается в том, что они:
- Не конфликтуют с свойствами и функциями, возвращенными контекстом отрисовки, в
setup - Идентификатор, доступный в глобальной области видимости, для режима Composition API Vue I18n
Таким образом, пользователь понимает, что они являются специальными свойствами и функциями.
УВЕДОМЛЕНИЕ
Если ваше приложение Vue не использует локальную область видимости и все i18n выполняется в глобальной области видимости, это очень полезно, поскольку не требуется запускать useI18n в setup для каждого компонента. Однако этот способ имеет проблему с глобальными переменными такого же характера. Используйте с осторожностью, особенно для больших приложений Vue.
Если вы используете его один раз и прекращаете его использование, вы должны изменить все свойства или функции, используемые в шаблонах, на те, которые возвращаются контекстом setup с использованием useI18n с опцией useScope: 'global'.
Локальная область видимости
В режиме Legacy API экземпляр VueI18n создается путем указания опции компонента i18n для каждого компонента. Это позволяет ресурсам, таким как локальные сообщения, управляемые экземпляром VueI18n, быть локальными областями видимости, которые могут быть доступны только целевому компоненту.
Чтобы включить локальную область видимости в режиме Composition API, необходимо установить опцию для useI18n, которая создаст новый экземпляр Composer на основе заданного языка, локальных сообщений и т.д. Когда указана опция, useI18n создает и возвращает новый экземпляр Composer на основе языка, локальных сообщений и других ресурсов, указанных в опции.
ПРИМЕЧАНИЕ
Вы можете явно указать опцию useScope: 'local'.
Следующий пример кода:
import { useI18n } from 'vue-i18n'
const { t, d, n, tm, locale } = useI18n({
locale: 'ja-JP',
fallbackLocale: 'en-US',
messages: {
'en-US': {
// ....
},
'ja-JP': {
// ...
}
},
datetimeFormats: {
'en-US': {
// ....
},
'ja-JP': {
// ...
}
},
numberFormats: {
'en-US': {
// ....
},
'ja-JP': {
// ...
}
}
})
// Что-то делаем здесь ...Локальные сообщения
Если вы используете пользовательские блоки i18n в SFC как ресурсы локальных сообщений, они будут объединены с локальными сообщениями, указанными в опции messages useI18n.
Следующий пример использования пользовательских блоков i18n и опций useI18n:
<script setup>
import { useI18n } from 'vue-i18n'
import en from './en.json'
const { t, availableLocales, getLocaleMessages } = useI18n({
locale: 'en',
messages: {
en
}
})
availableLocales.forEach(locale => {
console.log(`${locale} locale messages`, getLocaleMessages(locale))
})
</script>
<i18n locale="ja">
{
"hello": "こんにちは!"
}
</i18n>ПРИМЕЧАНИЕ
В этом примере определение ресурсов разделено между пользовательскими блоками i18n и опцией messages useI18n, но в локальной области видимости сообщения ресурсов указываются в опции messages как единое целое по административным причинам, либо все сообщения ресурсов определяются в пользовательских блоках i18n, что предпочтительно.
Общие локальные сообщения для компонентов
В режиме Legacy API общие локальные сообщения используются в компонентах с опцией sharedMessages.
В режиме Composition API используйте mergeLocaleMessage, экспортируемый useI18n.
Пример общих локальных сообщений:
export default {
en: {
buttons: {
save: "Save",
// ...
}
},
ja: {
buttons: {
save: "保存",
// ...
}
}
}Используйте mergeLocaleMessage в компонентах:
<script setup>
import { useI18n } from 'vue-i18n'
import commonMessages from './locales/common'
const { t, mergeLocaleMessage } = useI18n({
locale: 'en',
messages: {
en: {
hello: 'Hello!'
},
ja: {
hello: 'こんにちは!'
}
}
})
for (const locale of ['en', 'ja']) {
mergeLocaleMessage(locale, commonMessages[locale])
}
</script>Изменение языка
Глобальная область видимости
Вы хотите изменить язык с помощью <script setup>, просто получите глобальный Composer с помощью useI18n и измените его с помощью свойства locale экземпляра.
<script setup>
const { t, locale } = useI18n({ useScope: 'global' })
locale.value = 'en' // изменить!
</script>Вы также можете использовать контекст setup в шаблоне, который может быть изменен следующим образом:
<select v-model="locale">
<option value="en">en</option>
<option value="ja">ja</option>
</select>При изменении языка глобальной области видимости компоненты, зависящие от глобальной области видимости, такие как API перевода t, могут работать реактивно и переключать отображаемые сообщения на целевой язык.
Если вы используете неявный способ, вы также можете изменить его в шаблоне с помощью $i18n.locale, как показано ниже:
<select v-model="$i18n.locale">
<option value="en">en</option>
<option value="ja">ja</option>
</select>Локальная область видимости
Локальные языки локальной области видимости, то есть свойство locale экземпляра Composer, возвращенного useI18n, унаследованы от глобальной области видимости, как и в режиме Legacy API. Поэтому при изменении языка в глобальной области видимости унаследованный язык локальной области видимости также изменяется. Если вы хотите переключить язык для всего приложения, вы можете использовать locale, возвращенный useI18n({ useScope: 'global' }), или, если вы используете неявный способ, вы можете использовать $i18n.locale.
ПРИМЕЧАНИЕ
Если вы не хотите наследовать язык из глобальной области видимости, опция inheritLocale useI18n должна быть false.
УВЕДОМЛЕНИЕ
Изменения locale в локальной области видимости не влияют на язык глобальной области видимости, но только внутри локальной области видимости.
Соответствие между экземпляром VueI18n и экземпляром Composer
API, предлагаемый экземпляром Composer в Composition API, очень схож с интерфейсом API, предоставляемым экземпляром VueI18n.
ПРИМЕЧАНИЕ
Внутри экземпляр VueI18n режима Legacy API работает путем обертывания экземпляра Composer. По этой причине накладные расходы на производительность меньше в режиме Composition API, чем в режиме Legacy API.
Ниже приведена таблица сопоставления:
| Экземпляр VueI18n | Экземпляр Composer |
|---|---|
id | id |
locale | locale |
fallbackLocale | fallbackLocale |
availableLocales | availableLocales |
messages | messages |
datetimeFormats | datetimeFormats |
numberFormats | numberFormats |
modifiers | modifiers |
missing | getMissingHandler / setMissingHandler |
postTranslation | getPostTranslationHandler / setPostTranslationHandler |
silentTranslationWarn | missingWarn |
silentFallbackWarn | fallbackWarn |
formatFallbackMessages | fallbackFormat |
sync | inheritLocale |
warnHtmlInMessage | warnHtmlMessage |
escapeParameterHtml | escapeParameter |
t | t |
tc | t |
te | te |
tm | tm |
getLocaleMessage | getLocaleMessage |
setLocaleMessage | setLocaleMessage |
mergeLocaleMessage | mergeLocaleMessage |
d | d |
getDateTimeFormat | getDateTimeFormat |
setDateTimeFormat | setDateTimeFormat |
mergeDateTimeFormat | mergeDateTimeFormat |
n | n |
getNumberFormat | getNumberFormat |
setNumberFormat | setNumberFormat |
mergeNumberFormat | mergeNumberFormat |