iT邦幫忙

2023 iThome 鐵人賽

DAY 21
1
影片教學

Nuxt 3 快速入門系列 第 21

[影片教學] Nuxt 3 使用 I18n 建立多國語系

  • 分享至 

  • xImage
  •  

Yes

👆建議你可以使用影片子母畫面功能或全螢幕播放來獲得最佳的觀賞體驗,👇下方是本篇教學的相關筆記。


配置 Nuxt I18n

安裝 Nuxt I18n 套件

npm install -D @nuxtjs/i18n@next

開啟專案目錄下的 nuxt.config.ts,配置 Nuxi I18n 模組

export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  i18n: {
    langDir: 'locales',
    locales: [
      {
        code: 'en',
        iso: 'en-US',
        file: 'en.json'
      },
      {
        code: 'zh',
        iso: 'zh-TW',
        file: 'zh.json'
      }
    ]
  }
})

在專案目錄下建立 locales 資料夾,用來放置多個語系的翻譯檔案。

locales 目錄下建立一個檔案 ./locales/en.json

{
  "hello": "Hello!",
  "language": "Language"
}

locales 目錄下建立一個檔案 ./locales/zh.json

{
  "hello": "你好!",
  "language": "語言"
}

開啟 nuxt.config.ts 檔案,使用 defaultLocale: 'zh' 選項,調整 Nuxt I18n 配置預設使用語系

export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  i18n: {
    langDir: 'locales',
    locales: [
      {
        code: 'en',
        iso: 'en-US',
        file: 'en.json'
      },
      {
        code: 'zh',
        iso: 'zh-TW',
        file: 'zh.json'
      }
    ],
    defaultLocale: 'zh'
  }
})

建立多國語系頁面

pages 目錄下建立一個檔案 ./pages/index.vue

<template>
  <div class="flex flex-col items-center bg-white">
    <h1 class="my-8 text-6xl font-medium text-blue-500">
      {{ $t('hello') }}
    </h1>
  </div>
</template>

<script setup>
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
</script>

修改 app.vue 檔案:

 <template>
   <div>
    <NuxtPage />
   </div>
 </template>

調整多國語系路由策略

開啟 nuxt.config.ts 檔案,調整 Nuxt I18n 配置,添加 strategy: 'no_prefix',取消路由路徑語系代碼的前綴。

export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  i18n: {
    langDir: 'locales',
    locales: [
      {
        code: 'en',
        iso: 'en-US',
        file: 'en.json'
      },
      {
        code: 'zh',
        iso: 'zh-TW',
        file: 'zh.json'
      }
    ],
    defaultLocale: 'zh',
    strategy: 'no_prefix'
  }
})

切換不同語系

使用 locale 響應式狀態切換語系

調整 ./pages/index.vue 檔案:

<template>
  <div class="flex flex-col items-center bg-white">
    <h1 class="my-8 text-6xl font-medium text-blue-500">
      {{ $t('hello') }}
    </h1>
    <div class="flex gap-4">
      <button
        type="button"
        class="inline-flex items-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-700 hover:bg-blue-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
        @click="locale = 'en'"
      >
        English
      </button>

      <button
        type="button"
        class="inline-flex items-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-700 hover:bg-blue-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
        @click="locale = 'zh'"
      >
        繁體中文
      </button>
    </div>
    <div class="mt-4 flex flex-row justify-center">
      <label class="text-gray-600">{{ $t('language') }}</label>
      <span class="ml-4 font-bold text-gray-800">{{ locale }}</span>
    </div>
  </div>
</template>

<script setup>
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
</script>

使用 setLocale 函式切換語系

<template>
  <div class="flex flex-col items-center bg-white">
    <h1 class="my-8 text-6xl font-medium text-blue-500">
      {{ $t('hello') }}
    </h1>
    <div class="flex gap-4">
      <button
        type="button"
        class="inline-flex items-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-700 hover:bg-blue-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
        @click="setLocale('en')"
      >
        English
      </button>

      <button
        type="button"
        class="inline-flex items-center rounded-md border border-transparent bg-blue-100 px-4 py-2 text-sm font-medium text-blue-700 hover:bg-blue-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
        @click="setLocale('zh')"
      >
        繁體中文
      </button>
    </div>
    <div class="mt-4 flex flex-row justify-center">
      <label class="text-gray-600">{{ $t('language') }}</label>
      <span class="ml-4 font-bold text-gray-800">{{ locale }}</span>
    </div>
  </div>
</template>

<script setup>
import { useI18n } from 'vue-i18n'
const { locale, setLocale } = useI18n()
</script>

detectBrowserLanguage 配置

Nuxt I18n 模組的 detectBrowserLanguage 選項,可以用來配置語系代碼於 cookie 同步的策略。

export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  i18n: {
    langDir: 'locales',
    locales: [
      {
        code: 'en',
        iso: 'en-US',
        file: 'en.json'
      },
      {
        code: 'zh',
        iso: 'zh-TW',
        file: 'zh.json'
      }
    ],
    defaultLocale: 'zh',
    strategy: 'no_prefix',
    detectBrowserLanguage: {
      useCookie: true,
      cookieKey: 'i18n_redirected',
      redirectOn: 'root'
    }
  }
})

感謝大家的閱讀,歡迎大家給予建議與討論,也請各位大大鞭小力一些:)
如果對這個 Nuxt 3 系列感興趣,可以訂閱接收通知,也歡迎分享給喜歡或正在學習 Nuxt 3 的夥伴。

範例程式碼

參考資料


上一篇
[影片教學] Nuxt 3 Cookie 的設置與使用
下一篇
[影片教學] Nuxt 3 靜態資源的管理 - Public & Assets
系列文
Nuxt 3 快速入門30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言