Tips:本篇已加入系列文章閱讀目錄,可點擊查看更多相關文章。
前言
上一篇介紹了ABP擴展實體,並且在前端部分新增了身份認證管理和租戶管理的菜單,在實現這兩個功能模塊前,先來解決一下界面文字國際化的問題。
開始
國際化(簡稱 I18N),本地化(簡稱 L10N);這兩者的目的都是用於讓你的應用程序支持多個國家和區域的語言,它們看起來很相似,但是有一些細微的區別,本文不對此進行深入探討,有興趣的可以自行搜索。ABP后端支持的是本地化,而vue-element-admin支持的是國際化,使用vue-i18n實現;本文默認它兩者是一回事。
前面的章節中,已經大概分析了vue+ABP國際化的實現思路。我們可以在后端實現國際化,然后vue從后端獲取國際化文本,展示到界面中;另一種方式是直接在前端部分實現國際化。在前端實現就很簡單,直接在vue-element-admin的src\lang\
目錄下配置相應的文本,然后界面使用i18n的$t()
方法渲染就可以了,這個不多做介紹。本文只探討第一種實現方式。
語言選項
首先,語言選項列表需要根據后端配置得到。
在后端修改支持的語言類型,這里就只支持中文和英文2種吧,其他的注釋掉。
src\Xhznl.HelloAbp.HttpApi.Host\HelloAbpHttpApiHostModule.cs:
請求abp/application-configuration
接口:
此時返回的localization.languages屬性只有2個語言了,然后只需要把這個數據綁定到界面上就好了。語言切換用的是一個公共組件 src\components\LangSelect\index.vue:
<template>
<el-dropdown
trigger="click"
class="international"
@command="handleSetLanguage"
>
<div>
<svg-icon class-name="international-icon" icon-class="language" />
</div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item
v-for="item in languages"
:key="item.cultureName"
:disabled="language === item.cultureName"
:command="item.cultureName"
>
{{ item.displayName }}
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</template>
<script>
export default {
data() {
return {
languages: this.$store.getters.abpConfig.localization.languages
};
},
computed: {
language() {
return this.$store.getters.language;
}
},
methods: {
handleSetLanguage(lang) {
//this.$i18n.locale = lang
this.$store.dispatch("app/setLanguage", lang);
this.$store.dispatch("app/applicationConfiguration").then(() => {
this.$message({
message: "Switch Language Success",
type: "success"
});
});
}
}
};
</script>
語言切換
語言切換時,需要再次調用app/applicationConfiguration
接口,更新本地化文本。
src\utils\request.js:
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
config.headers['accept-language'] = store.getters.language
if (store.getters.token) {
config.headers['authorization'] = 'Bearer ' + getToken()
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
return Promise.reject(error)
}
)
src\store\modules\app.js:
const actions = {
。。。。。。
applicationConfiguration({ commit }) {
return new Promise((resolve, reject) => {
applicationConfiguration()
.then(response => {
const data = response;
commit("SET_ABPCONFIG", data);
const language = data.localization.currentCulture.cultureName;
const values = data.localization.values;
setLocale(language, values);
resolve(data);
})
.catch(error => {
reject(error);
});
});
}
};
src\lang\index.js:
import Vue from "vue";
import VueI18n from "vue-i18n";
import Cookies from "js-cookie";
import elementEnLocale from "element-ui/lib/locale/lang/en"; // element-ui lang
import elementZhLocale from "element-ui/lib/locale/lang/zh-CN"; // element-ui lang
Vue.use(VueI18n);
const messages = {
en: {
...elementEnLocale
},
"zh-Hans": {
...elementZhLocale
}
};
export function getLanguage() {
const chooseLanguage = Cookies.get("language");
if (chooseLanguage) return chooseLanguage;
// if has not choose language
const language = (
navigator.language || navigator.browserLanguage
).toLowerCase();
const locales = Object.keys(messages);
for (const locale of locales) {
if (language.indexOf(locale) > -1) {
return locale;
}
}
return "en";
}
export function setLocale(language, values) {
i18n.mergeLocaleMessage(language, values);
i18n.locale = language;
}
const i18n = new VueI18n({
// set locale
// options: en | zh | es
locale: getLanguage(),
// set locale messages
messages
});
export default i18n;
將后端返回的文本設置到vue-i18n中,就可以使用了。這跟直接在前端做國際化有一點區別就是,后者的文本信息是寫在前端,vue-i18n可以直接使用。而這里只是把文本信息改到后端,從后端獲取后再設置到i18n中,本質是一樣的。
修改后端的配置文本:
src\Xhznl.HelloAbp.Domain.Shared\Localization\HelloAbp\zh-Hans.json:
src\Xhznl.HelloAbp.Domain.Shared\Localization\HelloAbp\en.json:
localization.values返回:
接下來只需要把界面上對應的文本使用vue-i18n的$t()
方法渲染就好了,比如:
前端需要改動的地方比較多,但都是類似的修改。。。直接看效果:
注意
因為app/applicationConfiguration
接口只有在刷新頁面、登錄、退出、切換語言等操作的時候才會去調用,所以不用擔心請求頻繁。
其實上面有一部分本地化文本還是放在了前端:ElementUI自帶的文本。因為ABP的本地化json格式只能有一級,key/value:
文本只能寫在texts屬性中,key/value形式,不支持多層級。
而vue-i18n是支持多層級的:
所以ElementUI的這部分文本還是放在前端了。
最后
本篇關於vue+ABP實現國際化就介紹完了。。。其實還是有點繁瑣的,要配置的比較多,不知道有沒有更好的方法,歡迎評論交流。。。