package | version |
---|---|
vue | 2.6.11 |
vant | 2.12.6 |
vue-i18n | 8.23.0 |
最近一个用 react-mobile 的小型 IM App 被客户吐槽UI,所以现在用传说Vue中
最漂漂的
Vant 重构一下,没办法,react实在是没有省心又好看的移动端库了[手动哭脸T_T],所以喽,搞起!
模块代码如下:
import Vue from "vue";
import VueI18n from "vue-i18n";
import {
getLanguage } from "@/utils/cookies";
// Vant built-in lang
import {
Locale } from 'vant';
import enUS from "vant/es/locale/lang/en-US";
import zhCN from "vant/es/locale/lang/zh-CN";
import zhTW from "vant/es/locale/lang/zh-TW";
import jaJP from "vant/es/locale/lang/ja-JP";
// User defined lang
import enUsLocale from "./en_US";
import zhCnLocale from "./zh_CN";
import zhTwLocale from "./zh_TW";
import jaJpLocale from "./ja_JP";
Vue.use(VueI18n);
const messages = {
'zh-CN': {
...zhCN,
...zhCnLocale
},
'zh-TW': {
...zhTW,
...zhTwLocale
},
'en-US': {
...enUS,
...enUsLocale
},
'ja-JP': {
...jaJP,
...jaJpLocale
}
};
export const getLocale = () => {
const cookieLanguage = getLanguage();
if (cookieLanguage) {
document.documentElement.lang = cookieLanguage;
return cookieLanguage;
}
const language = navigator.language.toLowerCase();
const locales = Object.keys(messages);
for (const locale of locales) {
if (language.indexOf(locale) > -1) {
document.documentElement.lang = locale;
return locale;
}
}
// Default language is english
return "en-US";
};
const CURRENT_LANG = getLocale();
// first entry
Locale.use(CURRENT_LANG, messages[CURRENT_LANG])
const i18n = new VueI18n({
locale: CURRENT_LANG,
messages
});
export default i18n;
业务语言包结构如下:
export default {
appHeader: {
title: 'Vue App'
},
langSelect: {
pickerTitle: '当前语言',
}
};
getLanguage 是使用 js-cookie 封装的方法,cookie.js 代码如下:
import Cookies from 'js-cookie'
// App
const languageKey = 'language'
export const getLanguage = () => Cookies.get(languageKey)
export const setLanguage = (language) => Cookies.set(languageKey, language)
i18n模块关键点
引入 vant 内置默认语言包:
importenUS
from"vant/es/locale/lang/en-US"
importzhCN
from"vant/es/locale/lang/zh-CN"
......
引入项目业务组件语言包:
importenUsLocale
from"./en_US"
......
语言包整合成 messages 对象然后添加到 i18n 实例中,导出的 i18n 实例里设置的locale
属性仅设置组件内置的语言显示,业务组件语言显示需要使用vant
导出的Local.use
方法进行切换。
在
main.js
里引入 i18n 模块,添加到 Vue 实例中。
import Vue from "vue";
import "@/registerServiceWorker";
import App from "@/App.vue";
import router from "@/router";
import store from "@/store";
import i18n from '@/lang';
import 'amfe-flexible';
Vue.config.productionTip = false;
new Vue({
router,
store,
i18n,
render: h => h(App)
}).$mount("#app");
逻辑代码如下:
<template>
<van-popup
v-model="showPicker"
v-bind="popupConfig"
>
<van-picker
show-toolbar
item-height="1rem"
swipe-duration="300"
:title="$t('langSelect.pickerTitle')"
:columns="langs"
:default-index="defaultIndex"
@confirm="onConfirm"
@cancel="onClose"
/>
</van-popup>
</template>
<script>
import {
Popup, Picker, Toast, Locale } from 'vant';
import {
setLanguage } from "@/utils/cookies";
export default {
name: "LangSelect",
components: {
[Popup.name]: Popup,
[Picker.name]: Picker,
[Toast.name]: Toast
},
props: {
popupConfig: {
type: Object,
default: () => ({
overlay: true,
position: 'bottom',
duration: 0.3,
closeOnPopstate: true,
transitionAppear: true,
safeAreaInsetBottom: true
})
}
},
data() {
return {
langs: [
{
text: '中文(简体)',
value: 'zh-CN'
},
{
text: '中文(繁体)',
value: 'zh-TW'
},
{
text: 'English',
value: 'en-US'
},
{
text: '日本語',
value: 'ja-JP'
},
// {
// text: 'Español',
// value: 'en-US'
// },
// {
// text: '한국어',
// value: 'en-US'
// },
// {
// text: 'Italiano',
// value: 'en-US'
// }
]
};
},
computed: {
showPicker: {
get() {
return this.$store.getters.langPicker;
},
set(val) {
this.$store.dispatch('app/toggleLangPicker', val);
}
},
defaultIndex() {
return this.langs.findIndex(item => item.value === this.$i18n.locale) || 0;
}
},
methods: {
onConfirm({
value }) {
// Vant basic
Locale.use(value, this.$i18n.messages[value]);
// Business component
this.$i18n.locale = value;
// Cookie
setLanguage(value);
},
onClose() {
this.$store.dispatch('app/toggleLangPicker', false)
}
}
};
</script>
语言包在组件中的使用要点:
- 进行到这一步,在 template 中使用
$t('langSelect.pickerTitle')
就已经可以获取到自己设置的语言包了,逻辑代码中一样使用this.$t('langSelect.pickerTitle')
即可拿到。- 我代码里使用的是 Vant 的 Popup + Picker 封装的公用组件,需要注意语言切换的时候需要同时切换业务组件和内置组件的语言包,即使用:
Local.use('xxx', {...})
this.$i18n.locale = 'xxx' || 'en-US'
OK,vue + vant 的国际化到这就 over 了,对上述功能点有疑惑或者有更好的建议,欢迎留言~~