前端國際化


  最近做國外項目,需要實現項目的的國際化,這里大致捋一下思路、實現方式。項目技術棧是  vue + antd + java,我大致將需要翻譯的內容划分為如下5個部分,接下來會一個一個的說明為何這么區分、如何實現翻譯。這里強調一下,很負責的說,目前國際化,就是開發者寫對象,一個key關聯若干語種的翻譯,純手工翻譯,目前不存在任何一下代碼包可以一鍵智能翻譯(因為翻譯的不准)。ps:包括翻譯表格表頭,表頭和表格體同時翻譯都會說明

一、目錄:

1、菜單等靜態文本的國際化(I18n的使用,及其和antd的一些問題)

2、ui框架+其他外部依賴包的國際化

3、圖片的國際化

4、服務端返回的國際化(接口反饋+維護數據)

5、登錄頁等無用戶登錄信息的國際化

 

二、菜單等靜態文本的國際化

  這些基本的靜態信息的國際化,我采用   vue-i18n  這個包來實現的(詳細用法請查npm),指令: npm i vue-i18n ;用法很簡單,不過在觸發翻譯的機制上會有一些蛋疼的地方,待會具體寫一下。

1、引入、配置

import Vue from 'vue';
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)

const i18n = new VueI18n({
  //定義默認語言
  locale: 'zh', 
  messages:{
    'zh': require('@/constants/lang/zh'),  // 語言配置文件的路徑
    'us': require('@/constants/lang/us')
  }
})

new Vue({
    i18n,
    router
    render: (h) => h(App)
}).$mount('#app')
module.exports = {
  // 公共
  common: {
    // 按鈕類
    search: '查詢',
    reset: '重置',
    collapse: '展開',
    add: '新增',
    delete: '刪除',
    edit: '編輯',
    deleteMany: '批量刪除',
    import: '導入',
    export: '導出',
    yes: '是',
    no: '否',
    confirm: '確認',
    cancel: '取消',
    changeLanguage: '切換語言',
    // 表格信息類
    createName: '創建人員',
    createTime: '創建時間',
    updateName: '維護人員',
    updateTime: '維護時間',
    operation: '操作',
    // 提示類
    requireRule: '該項為必填項',
    dataImport: '數據導入',
  },
  // 提示信息
  message: {
      text: '簡體中文',
      delete: '確定要刪除嗎?',
      exportExcel: '正在導出Excel...',
      updateBom: '正在更新bom數據...',
      numberAndletter: '僅允許輸入數字和字母,並以英文逗號分隔'
  },
  // 文本提示
  placeholder: {
      input: '請輸入',
      select: '請選擇',
      rangePicker: '開始日期 ~ 結束日期'
  }
}

引入后需要做一個全局配置,目前我僅支持了中英,有需要的加不同語言配置文件即可。注意每個文本的分類,通常按照功能分類, 比如 一個一級菜單、通用按鈕、提示信息等等。

 

2、具體使用

// 在HTML中使用
<span>{{ $t(message.delete) }}</span>


// 在js中使用
this.$t(`message.exportExcel`)


// 切換語言
changeLanguage() {
        let lang = this.$store.state.app.language === 'zh' ? 'us' : 'zh';
        this.$i18n.locale = lang;
        this.$store.commit('CHANGE_LANGUAGE', lang )
},

語言屬於用戶屬性,存儲在數據庫,登陸成功后我將語言存儲在vuex中,只要是登陸的都可以保持語種狀態。

 

3、遇到的坑

基礎使用,自然沒問題,但是和別的包配合使用就遇到問題了,大致如下:

(1)antd 的table,翻譯他的表頭

  這個不能直接在js中翻譯columns,因為不會觸發自動轉換,需要表頭采用插槽的方式,如果是操作列需要翻譯表格體也是同理,具體看代碼

const columns = [
    {  // 只翻譯表頭
      dataIndex: 'area',
      key: 'area',
      widtd: 120,
      align: 'center',
      slotName: 'calendar.area',
      scopedSlots: { title: 'calendar.area' }
    },
    { // 操作類,翻譯表格體,比如翻譯 編輯 刪除 操作
      key: 'operation',
      fixed: 'right',
      widtd: 120,
      align: 'center',
      slotName: 'common.operation',
      scopedSlots: { title: 'common.operation', customRender: 'operationContent' },
    },
  ];

<a-table 
     rowKey="id" 
    :columns="columns" 
 >
      // 翻譯表頭
     <template v-for="(item, index) in columns" :slot="item.slotName">
           <span :key="index">{{ $t(item.slotName) }}</span>
      </template>
      // 操作類,翻譯表格體,比如翻譯 編輯 刪除 操
       <span slot="operationContent" slot-scope="text,record">
            <a @click="edit(record)"> {{ $t('common.edit') }}</a>      
        </span>
</a-table>

(2)路由數據的翻譯,因為 router 和 I18n 的引入是同時的,所以無法直接翻譯路由數據,只能在渲染菜單的時候進行翻譯,這個具體要看項目架構了。目前我的處理方式是路由配置價格國際化字段,渲染之前根據字段去判斷。

new Vue({
    store,
    i18n,
    router,
    created () {
        bootstrap()
    },
    render: (h) => h(App)
}).$mount('#app')
 
// 路由配置
{
  path: '/basicData/calendar/index/:usage',
  name: 'calendar',
  meta: {
  title: '工作日歷信息管理',
  international: 'calendar'   // 有這個字段就轉國際化覆蓋title值,沒有就用title
  },
  component: () => import('@views/basicData/calendar/index.vue')
}

 

三、ui框架+其他外部依賴包的國際化

  1、antd 是有國際化組件的,也是監聽vuex中語種字段,很簡單就實現的 I18n 和 a-locale-provider 的同步。具體使用如下:

<template>
  <a-locale-provider :locale="locale">
    <div id="app">
      <router-view/>
    </div>
  </a-locale-provider>
</template>

<script>
import { mapState } from 'vuex'
import en_GB from 'ant-design-vue/lib/locale-provider/en_GB'
import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
import { AppDeviceEnquire } from '@/utils/mixin'

export default {
    mixins: [AppDeviceEnquire],
    data () {
        return {}
    },
    computed: mapState({
      locale: state => state.app.language === 'zh' ? zhCN : en_GB,
    })
}
</script>

  2、其他包,比如 moment 等等,這個就得具體分析了,有的包根本就不支持,有的都是基於數據輸入的可以做。選包需慎重。

 

四、圖片的國際化

  圖片這種也分,如果像新聞這種每天更換的,直接服務端做區分,如果是固定的,就得做好幾套,一般直接存儲到不同語言目錄下,監聽全局的 language 變量展示不同路徑圖片即可

 

五、服務端返回的國際化(接口反饋+維護數據)

  服務端的國際化主要是2塊,一是:接口反饋信息,比如成功 失敗的提示信息,需要直接返回指定語言的,前端不做任何處理,直接展示; 二是: 配置信息,比如某個下拉列表的信息是需要放在服務端的,就需要服務端按照語言返回。前端當然也能做,但是有些場景不允許前端寫死,這類數據需要放在服務端。通常做法是數據加語種字段,用的時候篩選出來即可。

 

六、登錄頁等無用戶登錄信息的國際化

  我們通常會將語言信息寫到瀏覽器的 ocalstorage 中,如果涉及到沒有用戶信息的時候優先讀取 ocalstorage ,比如 登錄頁。這樣二次登錄的用戶是沒問題的。如果 ocalstorage  沒有,比如首次登陸、清楚本地緩存的情況,服務端會判斷其IP的地區,根據當前我們的語種支持范圍,選擇一個可能性最大的,比如,目前我們項目,除了歐美、中南亞用戶全部展示英文,中國展示中文。注意這個只是一個只能推薦,我們只考慮現實,VPN這種不考慮。另外建議登錄頁不要放太多文本類型的內容。

 

小結:

  好了,這就是我對項目國際化的一些總結,一方面自己做記錄,另一方面也希望能對大家有用吧。

 

 

 

 

 

 

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM