Многоязычность приложения на VueJS при помощи плагина Vue-l18n

Многоязычность приложения на VueJS 3

Для того что бы сделать наше приложение на нескольких языках нам нужно подключить в свой проект плагин Vue-l18n. Подключим его при помощи npm командой "npm install vue-i18n".

Подключим его к нашему приложению, для этого в main.js добавим строки "import { createI18n } from "vue-i18n"", "app.use(i18n)" и блок с константами.

main.js

/* jshint ignore:start */
import { createApp } from "vue"
import { createI18n } from "vue-i18n"
import App from "./App"
import Router from "./router"

import UIkit from "uikit"
import IMask from "imask"

const app = createApp(App)
const i18n = createI18n({
	locale: "en",
	fallbackLocale: "en",
	messages: {
		en: {
			message: {
				testTextOne: "asdsdf One En",
				testTextTwo: "asdsdf Two En",
				testTextThree: "asdsdf Three En"
			}
		},
		es: {
			message: {
				testTextOne: "asdsdf One Es",
				testTextTwo: "asdsdf Two Es",
				testTextThree: "asdsdf Three Es"
			}
		}
	}
})
app.use(i18n)
app.use(Router)
app.mount("#app")

Далее в компоненте где будет переключатель нашего языка добавляем код в раздел "script".

Код 

<script>
	export default {
		methods: {
			setLocale(locale) {
				this.$i18n.locale = locale
			}
		}
	}
</script>

А на переключатель языка вешаем директиву отслеживания клика по этому элементу.

К примеру так

											<div id="select_language_droop" uk-drop="mode: click">
												<div class="uk-menu-panel-nav-droop-items uk-animation-slide-top">
													<a class="uk-menu-panel-nav-droop-items-itm" href="#" @click="setLocale('en')">
														<img
															class="uk-menu-panel-nav-droop-items-itm-img"
															src="@/assets/images/flag-american.svg"
															alt=""
															uk-img
														>
													</a>
													<a class="uk-menu-panel-nav-droop-items-itm" href="#" @click="setLocale('es')">
														<img
															class="uk-menu-panel-nav-droop-items-itm-img"
															src="@/assets/images/flag.svg"
															alt=""
															uk-img
														>
													</a>
												</div>
											</div>

Затем в других компонентах, где нам нужна будет замена текста при выборе языка правим эти места кодом {{ $t('message.testTextOne') }}.

 

Константы перевода с применением HTML

Если вдруг нужны будут случаи, когда в переменных перевода нужно применить HTML теги то модно вомпользоваться одним из нескольких методов.

Применение директивы v-html при переводе с HTML тегами

К примеру "mesages" у нас состоит из таких блоков.

Пример

const i18n = createI18n({
	locale: "en",
	fallbackLocale: "en",
	messages: {
		en: {
			message: {
				ebikeRentalMainMsg: "LONG-RANGE<br>E-BIKE RENTAL<br>FROM",
				ebikeRentalMsg: "No deposits. No distance limits. If it breaks, we will fix it for free within 30 minutes or exchange the e-bike",
				ebikeRentalMobilMainMsg: "LONG-RANGE E-BIKE RENTALFROM",
				ebikeRentalMobilMsg: "No deposits. No distance limits. If it breaks, we will fix it for free within 30 minutes or exchange the e-bike",
				ebikeRentalButton: "Rent Now"
			}
		},
		es: {
			message: {
				ebikeRentalMainMsg: "ALQUILER DE<br>BICICLETAS<br>ELÉCTRICAS DE<br>LARGA<br>DURACIÓN<br>DESDE",
				ebikeRentalMsg: "Sin depósitos. Sin límites de distancia. Si se rompe, lo arreglaremos de forma gratuita en 30 minutos o cambiaremos la bicicleta eléctrica.",
				ebikeRentalMobilMainMsg: "ALQUILER DE BICICLETAS ELÉCTRICAS DE LARGA DURACIÓN DESDE",
				ebikeRentalMobilMsg: "Sin depósitos. Sin límites de distancia. Si se rompe, lo arreglaremos de forma gratuita en 30 minutos o cambiaremos la bicicleta eléctrica.",
				ebikeRentalButton: "Rentar Ahora"
			}
		}
	}
})

Тогда для отображения "ebikeRentalMainMsg" мы воспользуемся вот таким методом.

Код в компоненте

<p class="uk-001-main-leftblock-maintext">
	<span v-html="$t('message.ebikeRentalMainMsg')"></span>
		<span>
		$149/MO
		<img
		class="uk-001-main-leftblock-freeimg"
		src="@/assets/images/greenline.svg"
		alt=""
		uk-img
		>
		</span>
</p>

Но рекомендуется не использовать v-html, так как этот метод в Vue-i18n устарел, поэтому покажу пример как использовать тег "i18n-t".

Используем тег i18n-t при переводе с HTML тегами

Для этого заменяем в переменных наш <br> на {break}

const i18n = createI18n({
	locale: "en",
	fallbackLocale: "en",
	messages: {
		en: {
			message: {
				ebikeRentalMainMsg: "LONG-RANGE{break}E-BIKE RENTAL{break}FROM",
				ebikeRentalMsg: "No deposits. No distance limits. If it breaks, we will fix it for free within 30 minutes or exchange the e-bike",
				ebikeRentalMobilMainMsg: "LONG-RANGE E-BIKE RENTALFROM",
				ebikeRentalMobilMsg: "No deposits. No distance limits. If it breaks, we will fix it for free within 30 minutes or exchange the e-bike",
				ebikeRentalButton: "Rent Now"
			}
		},
		es: {
			message: {
				ebikeRentalMainMsg: "ALQUILER DE{break}BICICLETAS{break}ELÉCTRICAS DE{break}LARGA{break}DURACIÓN{break}DESDE",
				ebikeRentalMsg: "Sin depósitos. Sin límites de distancia. Si se rompe, lo arreglaremos de forma gratuita en 30 minutos o cambiaremos la bicicleta eléctrica.",
				ebikeRentalMobilMainMsg: "ALQUILER DE BICICLETAS ELÉCTRICAS DE LARGA DURACIÓN DESDE",
				ebikeRentalMobilMsg: "Sin depósitos. Sin límites de distancia. Si se rompe, lo arreglaremos de forma gratuita en 30 minutos o cambiaremos la bicicleta eléctrica.",
				ebikeRentalButton: "Rentar Ahora"
			}
		}
	}
})

Тогда для отображения "ebikeRentalMainMsg" мы воспользуемся вот таким методом.

Код в компоненте

<div class="uk-001-main-leftblock-desctop">
	<p class="uk-001-main-leftblock-maintext">
		<i18n-t keypath="message.ebikeRentalMainMsg" scope="global"><template #break><br></template></i18n-t>
		<span>
			$149/MO
			<img
				class="uk-001-main-leftblock-freeimg"
				src="@/assets/images/greenline.svg"
				alt=""
				uk-img
			>
		</span>
	</p>
	<p class="uk-001-main-leftblock-text"><i18n-t keypath="message.ebikeRentalMsg" scope="global"><template #break><br></template></i18n-t></p>
</div>

 

Выносим все настройки по мультиязычности сайта в отдельный JS файл

Гораздо удобнее вынести все что касается мультиязычности сайта в отдельный файл js. Для этого в папке src нашего проекта создаём файл "langs.js".

langs.js

import { createI18n } from "vue-i18n"

export default createI18n({
	locale: "en",
	fallbackLocale: "en",
	messages: {
		en: {
			message: {
				ebikeRentalMainMsg: "LONG-RANGE<br>E-BIKE RENTAL<br>FROM",
				ebikeRentalMsg: "No deposits. No distance limits. If it breaks, we will fix it for free within 30 minutes or exchange the e-bike",
				ebikeRentalMobilMainMsg: "LONG-RANGE E-BIKE RENTALFROM",
				ebikeRentalMobilMsg: "No deposits. No distance limits. If it breaks, we will fix it for free within 30 minutes or exchange the e-bike",
				ebikeRentalButton: "Rent Now"
			}
		},
		es: {
			message: {
				ebikeRentalMainMsg: "ALQUILER DE<br>BICICLETAS<br>ELÉCTRICAS DE<br>LARGA<br>DURACIÓN<br>DESDE",
				ebikeRentalMsg: "Sin depósitos. Sin límites de distancia. Si se rompe, lo arreglaremos de forma gratuita en 30 minutos o cambiaremos la bicicleta eléctrica.",
				ebikeRentalMobilMainMsg: "ALQUILER DE BICICLETAS ELÉCTRICAS DE LARGA DURACIÓN DESDE",
				ebikeRentalMobilMsg: "Sin depósitos. Sin límites de distancia. Si se rompe, lo arreglaremos de forma gratuita en 30 minutos o cambiaremos la bicicleta eléctrica.",
				ebikeRentalButton: "Rentar Ahora"
			}
		}
	}
})

А "main.js" делаем вида:

main.js

import { createApp } from "vue"
import App from "./App"
import Router from "./router"
import Languages from "./langs"

import UIkit from "uikit"
import IMask from "imask"

const app = createApp(App)

app.use(Router)
app.use(Languages)
app.mount("#app")

 

Выносим переменные перевода в json 

Так же возможно вынести переменные самого перевода в отдельный json файл. Для этого в папке "src" создаем папку "lang" и в ней файлы с переводами, в нашем случае это en.json и es.json.

en.json

{
  "ebikeRentalMainMsg": "LONG-RANGE<br>E-BIKE RENTAL<br>FROM",
  "ebikeRentalMsg": "No deposits. No distance limits. If it breaks, we will fix it for free within 30 minutes or exchange the e-bike",
  "ebikeRentalMobilMainMsg": "LONG-RANGE E-BIKE RENTALFROM",
  "ebikeRentalMobilMsg": "No deposits. No distance limits. If it breaks, we will fix it for free within 30 minutes or exchange the e-bike",
  "ebikeRentalButton": "Rent Now"
}

es.json

{
  "ebikeRentalMainMsg": "ALQUILER DE<br>BICICLETAS<br>ELÉCTRICAS DE<br>LARGA<br>DURACIÓN<br>DESDE",
  "ebikeRentalMsg": "Sin depósitos. Sin límites de distancia. Si se rompe, lo arreglaremos de forma gratuita en 30 minutos o cambiaremos la bicicleta eléctrica.",
  "ebikeRentalMobilMainMsg": "ALQUILER DE BICICLETAS ELÉCTRICAS DE LARGA DURACIÓN DESDE",
  "ebikeRentalMobilMsg": "Sin depósitos. Sin límites de distancia. Si se rompe, lo arreglaremos de forma gratuita en 30 minutos o cambiaremos la bicicleta eléctrica.",
  "ebikeRentalButton": "Rentar Ahora"
}
 

Тогда файл "langs.js" у нас будет такого вида:

langs.js

import { createI18n } from "vue-i18n"

export default createI18n({
	locale: "en",
	fallbackLocale: "en",
	messages: {
		en: {
			message: require("./lang/en.json")
		},
		es: {
			message: require("./lang/es.json")
		}
	}
})

 

Как менять HTML компонента при определенной локализации

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

script

<script>
	export default {
		data: function() {
			return {
				isLang: this.$i18n.locale
			}
		},
		watch: {
			isLang() {
				console.log (this.isLang)
			}
		},
		methods: {
			setLocale(locale) {
				this.$i18n.locale = locale
				this.isLang = locale
			}
		}
	}
</script>

При этом изменения в HTML мы будем делать через директиву "v-if".

v-if в HTML

<li>
									<a class="uk-navbar-droopdown-link" href="#">
										<img
											v-if="isLang ==='en'"
											class="uk-header-navbar-logo-flag"
											src="@/assets/images/flag-american.svg"
											alt=""
											uk-img
										>
										<img
											v-if="isLang ==='es'"
											class="uk-header-navbar-logo-flag"
											src="@/assets/images/flag.svg"
											alt=""
											uk-img
										>
										<img
											class="uk-header-navbar-logo-droopdown"
											src="@/assets/images/droopdown.svg"
											alt=""
											uk-img
										>
									</a>
									<div class="uk-navbar-dropdown">
										<ul class="uk-nav uk-navbar-dropdown-nav">
											<li v-if="isLang ==='es'">
												<a href="#" @click="setLocale('en')">
													<img
														class="uk-header-navbar-logo-flag"
														src="@/assets/images/flag-american.svg"
														alt=""
														uk-img
													>
												</a>
											</li>
											<li v-if="isLang ==='en'">
												<a href="#" @click="setLocale('es')">
													<img
														class="uk-header-navbar-logo-flag"
														src="@/assets/images/flag.svg"
														alt=""
														uk-img
													>
												</a>
											</li>
										</ul>
									</div>
								</li>

Ниже указан код непосредственно на компоненте в котором нет переключателя языка (и это как бы второй вариант отслеживания смены локализации).

script

<script>
	export default {
		data: function() {
			return {
				islang: this.$i18n.locale
			}
		},
		watch: {
			"$i18n.locale"(newLang, oldLang) {
				console.log (newLang, oldLang)
				this.islang = newLang
			}
		}
	}
</script>

 

Так же с моим портфолио можно ознакомиться на любой из представленной социальной сети, на своих страницах я публикую посты о своих работах, заданиях и целях.

Для связи со мной можно воспользоваться любой социальной сетью,
или написать на почту:

С моим резюме можно ознакомиться по ссылке:

© 2020-2024 Портфолио Юдина Александра г.Пенза. Все права защищены