Для того что бы сделать наше приложение на нескольких языках нам нужно подключить в свой проект плагин 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 теги то модно вомпользоваться одним из нескольких методов.
К примеру "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".
Для этого заменяем в переменных наш <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. Для этого в папке 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 файл. Для этого в папке "src" создаем папку "lang" и в ней файлы с переводами, в нашем случае это en.json и es.json.
en.json
es.json
Тогда файл "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")
}
}
})
Для того, что бы отслеживать изменения локализации мы будем использовать 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>