1. 程式人生 > >初識ABP vNext(6):vue+ABP實現國際化

初識ABP vNext(6):vue+ABP實現國際化

Tips:本篇已加入系列文章閱讀目錄,可點選檢視更多相關文章。 [TOC] # 前言 上一篇介紹了ABP擴充套件實體,並且在前端部分新增了身份認證管理和租戶管理的選單,在實現這兩個功能模組前,先來解決一下介面文字國際化的問題。 # 開始 國際化(簡稱 I18N),本地化(簡稱 L10N);這兩者的目的都是用於讓你的應用程式支援多個國家和區域的語言,它們看起來很相似,但是有一些細微的區別,本文不對此進行深入探討,有興趣的可以自行搜尋。ABP後端支援的是本地化,而vue-element-admin支援的是國際化,使用**vue-i18n**實現;本文預設它兩者是一回事。 前面的章節中,已經大概分析了vue+ABP國際化的實現思路。我們可以在後端實現國際化,然後vue從後端獲取國際化文字,展示到介面中;另一種方式是直接在前端部分實現國際化。在前端實現就很簡單,直接在vue-element-admin的`src\lang\`目錄下配置相應的文字,然後介面使用i18n的`$t()`方法渲染就可以了,這個不多做介紹。本文只探討第一種實現方式。 ## 語言選項 首先,語言選項列表需要根據後端配置得到。 ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815153213605-1308548692.png) 在後端修改支援的語言型別,這裡就只支援中文和英文2種吧,其他的註釋掉。 src\Xhznl.HelloAbp.HttpApi.Host\HelloAbpHttpApiHostModule.cs: ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815154714009-655262813.png) 請求`abp/application-configuration`介面: ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815155118711-186493352.png) 此時返回的localization.languages屬性只有2個語言了,然後只需要把這個資料繫結到介面上就好了。語言切換用的是一個公共元件 src\components\LangSelect\index.vue: ```vue ``` ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815164003204-797109963.png) ## 語言切換 語言切換時,需要再次呼叫`app/applicationConfiguration`介面,更新本地化文字。 src\utils\request.js: ```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: ```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: ```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: ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815165949871-1279611621.png) src\Xhznl.HelloAbp.Domain.Shared\Localization\HelloAbp\en.json: ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815171435896-1074821742.png) localization.values返回: ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815170306687-904958250.png) 接下來只需要把介面上對應的文字使用vue-i18n的`$t()`方法渲染就好了,比如: ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815170753017-375998060.png) 前端需要改動的地方比較多,但都是類似的修改。。。直接看效果: ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815172950076-1564810273.png) ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815173009829-1257301151.png) ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815172852552-1192780957.gif) ### 注意 因為`app/applicationConfiguration`介面只有在重新整理頁面、登入、退出、切換語言等操作的時候才會去呼叫,所以不用擔心請求頻繁。 其實上面有一部分本地化文字還是放在了前端:ElementUI自帶的文字。因為ABP的本地化json格式只能有一級,key/value: ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815174018143-1208829445.png) 文字只能寫在texts屬性中,key/value形式,不支援多層級。 而vue-i18n是支援多層級的: ![](https://img2020.cnblogs.com/blog/610959/202008/610959-20200815174421595-1027246779.png) 所以ElementUI的這部分文字還是放在前端了。 # 最後 本篇關於vue+ABP實現國際化就介紹完了。。。其實還是有點繁瑣的,要配置的比較多,不知道有沒有更好的方法,歡迎評論交流。。。