Vue.js vue-18n vue-router
▌Introduction
We will
implement i18n with
▋Related articles
▌Environment
▋Vue CLI 3.5.1 (with TypeScript
3.2.1)
▋vue-router 3.0.2
▋vue-i18n 8.9.0
▌Implement
▋Router
To create routes which can indicate current culture,
such as,
http://localhost/zh-TW/login
http://localhost/en-US/about
The routes patterns are set as
following,
▋router.ts
import Vue from 'vue';
import VueRouter from 'vue-router';
Vue.use(VueRouter);
const routes = [
{
name: 'home',
path: '/',
redirect: '/zh-tw/login',
},
{
name: 'app',
path: '/:lang',
component:
Home,
children: [
{ path: 'login', name: 'login', component:
Login },
{ path: 'about', name: 'about', component:
About },
],
},
];
export default new VueRouter({
routes,
mode: 'history',
});
routes,
mode: 'history',
});
▋Global Before Guards
We can
use vue-router’s Global
Before Guards to get
current-culture value from user’s navigation url, and then set the right i18n
data to vue-i18n.
Here is
the sample code which will implement requesting i18n data,loadLanguageAsync(…),
later.
router.beforeEach((to: any, from: any, next: any) => {
const lang =
to.params.lang;
const key =
to.query.key || to.name;
if
(supportedLanguages.indexOf(to.params.lang) >= 0) {
loadLanguageAsync(lang, key).then((response) => {
const msg = new
LocaleMsg(lang, response.data);
i18n.setLocaleMessage(msg.lang, msg.messages);
next();
});
} else {
// HACK:
Alert not supporting the language
next(false); // Fallback
to "from"'s url
}
});
The ajax
method for i18n data is as following,
const loadedLanguages: string[] = []; // Default
language that is preloaded if any
function loadLanguageAsync(lang: string, key:
string): Promise<any> {
if
(loadedLanguages.indexOf(lang) < 0) {
i18n.locale =
lang;
return getI18n(lang,
key);
} else {
return
Promise.resolve(() => {
i18n.locale =
lang;
});
}
}
function getI18n(lang: string, key: string):
AxiosPromise<any> {
const serverUrl:
string = process.env.VUE_APP_HOST_BACKEND_URL!;
const uri =
serverUrl.concat(`api/locale/get/${lang}/?key=${key}`);
return
axios.get(uri);
}
▋i18n
Now we can
create an i18n module to setup vue-i18n,
and set the i18n option to Vue instance.
▋i18n.ts
import Vue from 'vue';
import axios from 'axios';
import VueI18n, { LocaleMessages } from 'vue-i18n';
import router from '@/router';
Vue.use(VueI18n);
axios.defaults.withCredentials = false;
const supportedLanguages = ['en-us', 'zh-tw', 'zh-cn'];
const i18n = new VueI18n({
locale:
process.env.VUE_APP_I18N_LOCALE || 'zh-tw',
fallbackLocale:
process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'zh-tw',
});
// You can put the previous codes here…
export {supportedLanguages, i18n};
▋main.ts
import router from './router';
import { i18n } from '@/modules/i18n';
Vue.config.productionTip
new Vue({
router,
i18n,
render: (h) => h(App),
}).$mount('#app');
▋Demo
▌Reference