iT邦幫忙

2021 iThome 鐵人賽

DAY 28
0
Modern Web

Vue.js 什麼意思系列 第 28

Day 28:順手挖洞給 i 跳-vue-i18n

基本上設置多國語系算是相對簡單的事情,只要在 <template> 中有使用模板語法的位置,加上 $t() 放入變數即可。因此可以的話,會建議在專案初期先處理好語系設定,即使各語系的內容尚未定案也沒關係,先放空字串當作假資料即可,重點是提前在 <template> 挖空的同時也為 $t() 完成佈局,之後只要更新語系 json 檔的字串就能照常渲染出對應內容,如此便能省去回頭修改模板語法的重工步驟。

設置語系 json 檔案

  • zh.json

    {
      "message": "哈囉~~~ i18n !!",
      "navItem": {
        "all": "全部書單",
        "30off": "七折區",
        "50off": "五折區",
        "ithelp": "iT邦幫忙鐵人賽系列書"
      },
      "language": {
        "select": "選擇語系",
        "zh": "中文",
        "en": "英文"
      }
    }
    
  • en.json

    {
      "message": "hello i18n !!",
      "navItem": {
        "all": "All Books",
        "30off": "Discount 30% OFF",
        "50off": "Discount 50% OFF",
        "ithelp": "IThome Ironman Series"
      },
      "language": {
        "select": "Language",
        "zh": "Chinese",
        "en": "English"
      }
    }
    

$t

基本用法

  • 一般 <template> 模板語法

    <h2>{{ message }}</h2>
    
  • 在 <template> 使用 $t

    <h2>{{ $t("message") }}</h2>
    

綁定 prop

  • 在父元件綁定 prop
    <b-nav-item-dropdown :text="$t('language.select')">
    

套用 data

如果以基本用法會是 {{ $t('navItem.all') }}{{ $t('navItem.30off') }} 依此類推顯示出導覽項目的語系內容,但目前導覽項目是使用 v-for 遞迴取得 navItem.item 的資料,因此稍微轉換一下對應關係:

  • 原始子元件內容

    <b-navbar-nav
    	class="my_navbar_item"
    	v-for="navItem in navList"
    	:key="navItem.id"
    >
    	<router-link :to="{ name: navItem.name }" class="nav-link">
    		{{ navItem.item }}
    	</router-link>
    </b-navbar-nav>
    
    data() {
      return {
        navList: [
          { id: 1, item: "全部書單", name: "All" },
          { id: 2, item: "七折區", name: "Discount30" },
          { id: 3, item: "五折區", name: "Discount50" },
          { id: 4, item: "iT邦幫忙鐵人賽系列書", name: "Ithelp" },
        ],
      };
    },
    
  • 加入語系設定
    <template> 的部分一樣是用 $t() 包裹 navItem.item 即可,不過必須將 item 改成 'navItem.all',這樣組合起來就會是相當於 {{ $t('navItem.all') }} 的形式了!

    <!-- 略 -->
    <router-link :to="{ name: navItem.name }" class="nav-link">
    	{{ $t(navItem.item) }}
    </router-link>
    
    data() {
      return {
    	navList: [
    	  { id: 1, item: "navItem.all", name: "All" },
          { id: 2, item: "navItem.30off", name: "Discount30" },
          { id: 3, item: "navItem.50off", name: "Discount50" },
          { id: 4, item: "navItem.ithelp", name: "Ithelp" },
        ],
      };
    },
    

監聽 click 事件切換語系

當初使用 BootstrapVue Navbar 元件時,語系項目是在 <b-dropdown-item> 設置,文件中 有說明此元件有 $emit 傳出 click 事件可供使用。

監聽觸發 click 事件時須改變當前語系 $i18n.locale

<b-dropdown-item href="#" @click="$i18n.locale = 'en'">EN</b-dropdown-item>
<b-dropdown-item href="#" @click="$i18n.locale = 'zh'">ZH</b-dropdown-item>

如果要設置的再完整一點,則可將使用者選擇的語系記錄到 localStorage 中;另外,也一起把其他文案的位置都完成語系設定。

<b-nav-item-dropdown :text="$t('language.select')" right>
    <b-dropdown-item href="#" @click="selectLanguage('en')">
        {{ $t("language.en") }}
	</b-dropdown-item>
	<b-dropdown-item href="#" @click="selectLanguage('zh')">
		{{ $t("language.zh") }}
	</b-dropdown-item>
</b-nav-item-dropdown>
methods: {
  selectLanguage(language) {
    this.$i18n.locale = language;
    localStorage.setItem("locale", language);
  },
},

剛才有設定 $t 的位置,包括導覽項目、切換下拉選單、版面內容,都能成功切換語系了!

英文版
en

中文版
zh

參考資料


上一篇
Day 27:語系包在 i 身上-Vue I18n 前置作業
下一篇
Day 29:神奇語法糖-v-model
系列文
Vue.js 什麼意思30

1 則留言

0
juck30808
iT邦新手 3 級 ‧ 2021-10-14 12:37:46

恭喜即將邁入完賽~

Teen iT邦新手 5 級 ‧ 2021-10-15 11:09:41 檢舉

終於~/images/emoticon/emoticon07.gif

我要留言

立即登入留言