Работать с Vue.js одно удовольствие. Элегантный дизайн, а надежные сторонние дополнения, которые можно сочетать, превращают создание браузерных приложений в удовольствие.
Самым известным плагином i18n для прогрессивного JavaScript-фреймворка Vue.js, вероятно, является Vue I18n.
Казуя, спасибо за этот замечательный плагин для i18n!
новые версии
Помимо шаблонов, директив, привязки данных, обработки событий и т. д., в v3 Vue.js теперь также представляет Composition API, Teleport, Fragments… и Suspense.
Соответствующая версия для Vue. js v3 для Vue I18n — v9.
Так как же выглядит базовая установка vue-i18n?
Давайте углубимся в это…
Предпосылки
Убедитесь, что у вас установлены Node.js и npm. Лучше всего, если у вас есть некоторый опыт работы с простым HTML, JavaScript и базовым Vue.js, прежде чем переходить к vue-i18n.
Начиная
Возьмите свой собственный проект Vue.js или создайте новый, то есть с помощью команды vue create cli.
npx @vue/cli create vue-starter-project
# select vue 3 preset
Давайте установим зависимость vue-i18n:
npm install vue-i18n@9
Подготовим файл main.js
:
import { createApp } from 'vue' import { createI18n } from 'vue-i18n'; import App from './App.vue'
export const i18n = createI18n({ locale: 'en', // set locale fallbackLocale: 'en', // set fallback locale messages: { en: { message: { welcome: 'Welcome to Your Vue.js App' } }, de: { message: { welcome: 'Willkommen zu Deiner Vue.js App' } } } // If you need to specify other options, you can set other options // ... })
createApp(App).use(i18n).mount('#app')
Теперь давайте создадим первый компонент TranslationShowCase.vue
:
<template> <div class="hello"> <h1>{{ $t("welcome") }}</h1> </div> </template>
<script> export default { name: 'TranslationShowCase' } </script>
…и использовать этот компонент в App.vue
:
<template> <img alt="Vue logo" src="./assets/logo.png"> <TranslationShowCase /> </template>
<script> import TranslationShowCase from './components/TranslationShowCase.vue'
export default { name: 'App', components: { TranslationShowCase } } </script>
<style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
Теперь вы должны увидеть что-то вроде этого:
Переключатель языков
Теперь мы создадим переключатель языка, чтобы содержимое менялось между разными языками.
<template> <div class="hello"> <h1>{{ $t("welcome") }}</h1> </div> <hr /> <div> <div> <a v-if="$i18n.locale !== 'de'" v-on:click="changeLanguage('de')">DE</a> <strong v-if="$i18n.locale === 'de'">DE</strong> | <a v-if="$i18n.locale !== 'en'" v-on:click="changeLanguage('en')">EN</a> <strong v-if="$i18n.locale === 'en'">EN</strong> </div> </div> </template>
<script> export default { name: 'TranslationShowCase', methods: { changeLanguage(lang) { this.$i18n.locale = lang } } } </script>
🥳 Отлично, вы только что создали свой первый переключатель языков!
Компонентная интерполяция и директива
Теперь попробуем компонентную интерполяцию и директиву перевода:
<template> <div class="hello"> <h1>{{ $t("welcome") }}</h1> </div> <p> <i18n-t keypath="descr" tag="label" for="doc"> <a href="https://cli.vuejs.org" target="_blank">{{ $t('doc') }}</a> </i18n-t> </p> <div> <div> <span v-t="{path:'end'}" /> <!-- can also be written like: <i v-t="'end'" /> --> </div> </div> <hr /> <div> <div> <a v-if="$i18n.locale !== 'de'" v-on:click="changeLanguage('de')">DE</a> <strong v-if="$i18n.locale === 'de'">DE</strong> | <a v-if="$i18n.locale !== 'en'" v-on:click="changeLanguage('en')">EN</a> <strong v-if="$i18n.locale === 'en'">EN</strong> </div> </div> </template>
<script> export default { name: 'TranslationShowCase', methods: { changeLanguage(lang) { this.$i18n.locale = lang } } } </script>
…и добавьте новые ключи к вашим переводам:
import { createApp } from 'vue' import { createI18n } from 'vue-i18n' import App from './App.vue'
export const i18n = createI18n({ locale: 'en', // set locale fallbackLocale: 'en', // set fallback locale messages: { en: { message: { welcome: 'Welcome to Your Vue.js App', descr: 'For a guide and recipes on how to configure / customize this project, check out the {0}.', doc: 'vue-cli documentation', end: 'have fun!' } }, de: { message: { welcome: 'Willkommen zu Deiner Vue.js App', descr: 'Eine Anleitung und Rezepte für das Konfigurieren / Anpassen dieses Projekts findest du in der {0}.', doc: 'vue-cli Dokumentation', end: 'habe Spass!' } } } // If you need to specify other options, you can set other options // ... })
createApp(App).use(i18n).mount('#app')
Это должно быть результатом:
Где дополнительные сверхспособности?
Знакомимся с locizer…
locizer — это легкий модуль для доступа к данным из вашего проекта locize и использования их внутри вашего приложения.
Как это выглядит?
Сначала нужно зарегистрироваться в locize и войти.
Затем создать новый проект в locize и добавить свои переводы. Вы можете добавить свои переводы либо путем импорта отдельных файлов json, либо через API, либо с помощью CLI.
Наличие переводов в вашем файле кода работает, но не совсем подходит для работы с переводчиками.
Использование locize отделяет переводы от кода.
Импорт всех переводов должен выглядеть так:
Сделав это, мы собираемся установить locizer.
npm install locizer
Давайте создадим специальный файл i18n.js
:
import { createI18n } from 'vue-i18n' import locizer from 'locizer'
const namespace = 'messages' // your namespace name added in locize locizer.init({ projectId: 'your-locize-project-id' })
export const i18n = createI18n({ locale: locizer.lng, // locizer.lng is the language detected in your browser. fallbackLocale: 'en' // set fallback locale // If you need to specify other options, you can set other options // ... })
// called from within setup hook in App.vue export const loadMessagesPromise = new Promise((resolve, reject) => { locizer.loadAll(namespace, (err, messages) => { if (err) return reject(err); Object.keys(messages).forEach((l) => { i18n.global.setLocaleMessage(l, messages[l]) }) resolve(messages) }) })
Переводы теперь загружаются асинхронно, поэтому мы экспортируем loadMessagesPromise
и используем его в вашем App.vue
:
<template> <img alt="Vue logo" src="./assets/logo.png"> <TranslationShowCase /> </template>
<script> import { loadMessagesPromise } from './i18n' import TranslationShowCase from './components/TranslationShowCase.vue'
export default { name: 'App', components: { TranslationShowCase }, // used in combination with Suspense. // useful when translations are not in-memory... async setup() { await loadMessagesPromise return {} } } </script>
<style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
Кроме того, мы используем новую функцию Приостановка Vue.js.
Давайте создадим новый файл: например, Suspenser.vue
:
<template> <Suspense> <template #default> <App /> </template> <template #fallback> <span>Loading...</span> </template> </Suspense> </template>
<script> import App from './App.vue'
export default { name: 'Suspenser', components: { App } } </script>
И используйте это в своем файле main.js
:
import { createApp } from 'vue' import { i18n } from './i18n' import App from './Suspenser.vue'
createApp(App).use(i18n).mount('#app')
Теперь, пока ваши переводы загружены, вы увидите резервный шаблон:
Если ваш браузер настроен на немецкий язык, вы, возможно, заметили, что по умолчанию язык был автоматически установлен на немецкий. Это связано с функцией определения языка locizer. Вы можете настроить определение языка с помощью других параметров
По умолчанию определение языка также ищет параметр запроса lng, поэтому вы также можете ввести этот URL-адрес, чтобы проверить это: http://localhost:8080/? lng=de
сохранить недостающие переводы
Я хочу, чтобы новые ключи, добавленные в код, автоматически сохранялись для локализации.
Ваше желание – моя команда!
Расширьте файл i18n.js
с помощью locize api-key и функции handleMissing:
import { createI18n } from 'vue-i18n' import locizer from 'locizer'
const namespace = 'messages' // your namespace name added in locize const apiKey = 'my-api-key' // used for handleMissing functionality, do not add your api-key in a production build locizer.init({ projectId: 'your-locize-project-id', apiKey })
export const i18n = createI18n({ locale: locizer.lng, // locizer.lng is the language detected in your browser. fallbackLocale: 'en' // set fallback locale // If you need to specify other options, you can set other options // ... })
// called from within setup hook in App.vue export const loadMessagesPromise = new Promise((resolve, reject) => { locizer.loadAll(namespace, (err, messages) => { if (err) return reject(err); Object.keys(messages).forEach((l) => { i18n.global.setLocaleMessage(l, messages[l]) }) resolve(messages) }) })
export function handleMissing (locale, key) { if (!apiKey) return if (locale !== locizer.referenceLng) return locizer.add(namespace, key, key) }
И используйте его в компоненте:
<template> <img alt="Vue logo" src="./assets/logo.png"> <TranslationShowCase /> </template>
<script> import { useI18n } from 'vue-i18n' import { loadMessagesPromise, handleMissing } from './i18n' import TranslationShowCase from './components/TranslationShowCase.vue'
export default { name: 'App', components: { TranslationShowCase }, // used in combination with Suspense. // useful when translations are not in-memory... async setup() { useI18n().setMissingHandler(handleMissing) await loadMessagesPromise return {} } } </script>
<style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style>
Теперь, если вы добавите новый ключ в свои шаблоны, <h2>{{ $t("How are you?") }}</h2>
:
<template> <div class="hello"> <h1>{{ $t("welcome") }}</h1> <h2>{{ $t("How are you?") }}</h2> </div> <p> <i18n-t keypath="descr" tag="label" for="doc"> <a href="https://cli.vuejs.org" target="_blank">{{ $t('doc') }}</a> </i18n-t> </p> <div> <div> <span v-t="{path:'end'}" /> <!-- can also be written like: <i v-t="'end'" /> --> </div> </div> <hr /> <div> <div> <a v-if="$i18n.locale !== 'de'" v-on:click="changeLanguage('de')">DE</a> <strong v-if="$i18n.locale === 'de'">DE</strong> | <a v-if="$i18n.locale !== 'en'" v-on:click="changeLanguage('en')">EN</a> <strong v-if="$i18n.locale === 'en'">EN</strong> </div> </div> </template>
<script> export default { name: 'TranslationShowCase', methods: { changeLanguage(lang) { this.$i18n.locale = lang } } } </script>
Он автоматически сохраняется для определения местоположения:
Наконец, с помощью рабочего процесса автоматического машинного перевода новые ключи не только добавляются для автоматической локализации при разработке приложения, но также автоматически переводятся на целевые языки с помощью машинного перевода:
👀 но есть еще…
🧑💻 Код можно найти здесь.
🎉🥳 Поздравляем 🎊🎁
Надеюсь, вы узнали что-то новое о локализации Vue.js и современных рабочих процессах локализации.
Так что, если вы хотите вывести свою тему i18n на новый уровень, стоит попробовать locize.