教你如何在vue中使用國際化

引言:對(duì)于一些跨國項(xiàng)目來說,國際化是尤為重要的,那么什么要國際化呢?國際化的意思就是將我們寫的項(xiàng)目,能夠根據(jù)不同國家的語言,進(jìn)行翻譯,進(jìn)行切換,方便不同國家的客戶使用。

本文展示了在vue中如何使用國際化來更改咱們的項(xiàng)目語言,首先我們需要安裝i18n這個(gè)插件

1、i18n

1.1、i18n的安裝

i18ninternationalization這個(gè)單詞的縮寫,取了首字母i和結(jié)尾字母n,中間一用有18個(gè)字母,所以組合起來就所寫成i18n,這是一個(gè)用于給vue國際化的插件, 它可以輕松地將一些本地化功能集成到你的 Vue.js 應(yīng)用程序中

安裝 | Vue I18n?kazupon.github.io

//使用yarn
yarn add vue-i18n 
//npm
npm i vue-i18n -S

1.2、i18n基本使用

如果在一個(gè)模塊系統(tǒng)中使用它,必須通過 Vue.use() 明確地安裝 vue-i18n

假如當(dāng)前的目錄是src/i18n/index.js

//src/i18n/index.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'

Vue.use(VueI18n)
// 準(zhǔn)備翻譯的語言環(huán)境信息
const messages = {
  en: { 
    message: {
      hello: 'hello world'
    }
  },
  ja: {
    message: {
      hello: 'こんにちは、世界'
    }
  }
}

// 通過選項(xiàng)創(chuàng)建 VueI18n 實(shí)例
const i18n = new VueI18n({
  locale: 'ja', // 設(shè)置地區(qū)
  messages // 設(shè)置地區(qū)信息
})

上面代碼中的messages對(duì)象中有兩個(gè)屬性,屬性名分別是enja其實(shí)在i18n中這兩個(gè)字段是和下面new VueI18n實(shí)例中的locale里的值相對(duì)應(yīng)的,而messages對(duì)象又作為了new VueI18n的實(shí)例屬性,所以當(dāng)locale的值是ja的時(shí)候,那么會(huì)加載messages.ja這個(gè)對(duì)象中的內(nèi)容

接下來,我們需要將這個(gè)i18n實(shí)例掛載在Vue的option中

import Vue from 'vue'
import i18n from "./src/i18n/index.js"
new Vue({
    i18n
})

那么如何在視圖中呈現(xiàn)呢,其實(shí)也很簡單,我們只需要在插值中使用$t這個(gè)函數(shù)就可以了

<div id="app">
  <p>{{ $t("message.hello") }}</p>
</div>

最終展示的效果是

<div id="app">
 <p>hello world</p>
</div>

是不是很簡單,當(dāng)然這是咱們對(duì)i18n最基礎(chǔ)的使用,如果想要更深入的使用,可以查看

開始 | Vue I18n?kazupon.github.io

2、在vue-cli項(xiàng)目中使用

2.1、創(chuàng)建i18n文件結(jié)構(gòu)

我們首先在項(xiàng)目中src目錄下建立一個(gè)叫做i18n的文件夾,路徑為/src/i18n 當(dāng)前的例子只提供兩種語言(多了寫的累-_-||),分別是en英文zh中文,格式如下建立就可以了,我們秉承著高內(nèi)聚低耦合的思路,所以把原本i18n實(shí)例中messages中的屬性進(jìn)行模塊化拆分為兩個(gè)文件,如下圖,都放置在config文件夾中

image

2.2、config中兩個(gè)文件的內(nèi)容定義

en.jszh.js我們可以先定義一些內(nèi)容

en.js

export default {
    table: {//假如用于翻譯表格
        date: "Date",
        name: "Name",
        address: "Address"
    },
    menu: {},//假如項(xiàng)目中日后還有菜單
    tabs: {}//tab切換等
}

zh.js

export default {
    table: {
        date: "日期",
        name: "姓名",
        address: "地址"
    },
    menu: {},
    tabs: {}
}

2.3、配置i18n文件夾下的index.js文件

目前我們已經(jīng)對(duì)兩個(gè)js文件進(jìn)行了配置,接下來,我們來配置下/src/i18n/index.js文件,我們在開發(fā)過程中都知道,如果一個(gè)路由或者api有很多內(nèi)容都寫在一個(gè)文件,容易造成維護(hù)災(zāi)難,繼續(xù)秉承高內(nèi)聚低耦合的思路,我們和對(duì)項(xiàng)目中的路由或者api進(jìn)行model劃分,本文中的兩個(gè)語言配置enzh也是劃分模塊,但是如果我們有20幾個(gè)國家的語言需要翻譯,我們在index中一個(gè)一個(gè)的import顯然對(duì)開發(fā)效率來書是中災(zāi)難,我們的代碼可能這樣

import en from './config/en'
import id from './config/id'
import ja from './config/ja'
import ae from './config/ae'
import am from './config/am'
import ca from './config/ca'
import al from './config/al'
.....

為了解決這個(gè)問題,本文采用了webpack中的require.context方法來解決這個(gè)問題

2.4、使用require.context()

require.context是webpack提供的方法,用這個(gè)方法我們可以批量引入我們想要的文件,require.context可以返回一個(gè)具有 resolve, keys, id 三個(gè)屬性的方法

  1. resolve() 它返回請求被解析后得到的模塊 id
  2. keys() 它返回一個(gè)數(shù)組,由所有符合上下文模塊處理的請求組成
  3. id 是上下文模塊里面所包含的模塊 id. 它可能在你使用 module.hot.accept 的時(shí)候被用到

這個(gè)方法接受3個(gè)參數(shù)

  1. dir傳入一個(gè)目錄進(jìn)行搜索 <String>
  2. child是否要搜索子目錄<Boolean>
  3. regExp傳入正則表達(dá)式來匹配哪些文件需要引入<RegExp>
let langFiles = require.context("./config", false, /\.js$/);

當(dāng)我們調(diào)用kes()方法的時(shí)候可以得到如下屬性

let langFiles = require.context("./config", false, /\.js$/);
console.log(langFiles.keys())//["./cn.js","./zh.js"]

以上便是require.context的簡單使用,如果想要知道更詳細(xì)的用法,那我后續(xù)會(huì)再開一期關(guān)于require.context的專題,敬請期待

2.5、繼續(xù)配置/src/i18n/index.js

下面的代碼中我使用了一個(gè)正則表達(dá)式

let reg = /^\.\/([^\.]+)\.([^\.]+)$/ //正則用于匹配文件名

用這個(gè)正則的目的是為了,我們需要將數(shù)據(jù)處理成這樣

{
    zh:{...},
    en:{...}
}

處理成這種i18nmessage屬性對(duì)應(yīng)的數(shù)據(jù)模式,我們通過forEach獲取下來的key是這種類型的./zh.js使用正則的目的就是截取其中的zh兩個(gè)字符,然后生成復(fù)合message屬性的數(shù)據(jù)模型

import Vue from "vue"
import VueI18n from "vue-i18n"
Vue.use(VueI18n)//注入到所有的子組件

//require.context(path,deep,regExp)
//有3個(gè)方法 分別是keys() 

let langFileds = require.context('./config', false, /\.js$/)

let regExp = /\.\/([^\.\/]+)\.([^\.]+)$/ //正則用于匹配 ./en.js中的'en'

// regExp.exec('./en.js')

let messages = {} //聲明一個(gè)數(shù)據(jù)模型,對(duì)應(yīng)i18n中的message屬性

langFileds.keys().forEach(key => {
    let prop = regExp.exec(key)[1] //正則匹配en|zh這樣的值
    //messages[prop]相當(dāng)于 messages['en'] = {table:{...}}
    messages[prop] = langFileds(key).default

})
console.log(messages);
console.log(langFileds('./en.js'));

let locale = localStorage.getItem('lang') || "zh" //從localstorag中獲取

export default new VueI18n({
    locale,//指定語言字段
    messages//定義語言字段
})

2.6、修改main.js

下面我們將i18n掛載在main的Vue實(shí)例,本案例中也引入了element-ui,如果想要使用element-ui,需要先安裝

yarn add element-ui

接下來根據(jù)自己的需求編寫代碼

import Vue from 'vue'
import App from './App.vue'
import ElementUI from "element-ui" //element-ui
import 'element-ui/lib/theme-chalk/index.css';
Vue.config.productionTip = false
Vue.use(ElementUI)

import i18n from "./i18n" //

new Vue({
  render: h => h(App),
  i18n //掛載
}).$mount('#app')

2.7、 App.vue視圖展示(navigator.language)

2.5的代碼中我們可以看到,我將locale的屬性設(shè)置為從localStorage中獲取,是為了達(dá)到快速的演示效果,但是如果我們在開發(fā)中的話要通過計(jì)算機(jī)的語言來判斷,并且進(jìn)行切換,正確的方法是我們通過navigator.language來獲取計(jì)算機(jī)的語言

<template>
  <div id="app">
    <template>
      <el-table :data="tableData"
                style="width: 100%">
        <el-table-column prop="date"
                         :label="$t('table.date')"
                         width="180">
        </el-table-column>
        <el-table-column prop="name"
                         :label="$t('table.name')"
                         width="180">
        </el-table-column>
        <el-table-column prop="address"
                         :label="$t('table.address')">
        </el-table-column>
      </el-table>

    </template>
    <el-button type="primary"
               @click="change('zh')">點(diǎn)擊切換中文</el-button>
    <el-button type="primary"
               @click="change('en')">點(diǎn)擊切換英文</el-button>
    <el-button type="primary"
  </div>
</template>
 <script>
  export default {
    mounted() {
      console.log(this.$i18n.t('table.date'));
    },
    methods: {
      change(lang) { //切換方法
        localStorage.setItem('lang', lang)
        window.location.reload() //localSotrage是不響應(yīng)的,為了演示效果所以直接調(diào)用刷新
      }
    },
    data() {
      return {
        tableData: [{
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀區(qū)金沙江路 1518 弄'
        }, {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀區(qū)金沙江路 1517 弄'
        }, {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀區(qū)金沙江路 1519 弄'
        }, {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀區(qū)金沙江路 1516 弄'
        }]
      }
    }
  }
  </script>
  <style>
  #app {
    width: 50%;
  }
</style>

2.8、效果

表頭的翻譯效果 此處多加了兩種語言

image

點(diǎn)擊鏈接查看效果

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容