SwLangSwitch

SwLangSwitch 是內建語言切換器:讀取 @nuxtjs/i18n 的 i18n.locales,自動列出可選語言並渲染一個「地球圖示 + <select>」,選項標籤取 locale 的 name 欄位兜底 code。

自 gate:元件透過執行期探測 $i18n(framework 僅在 swift.config.json 的 i18n.enabled 時註冊該模組)——i18n 未啟用、或可選語言 ≤ 1 種時渲染為空。所以模板裡直接放 <SwLangSwitch /> 即可,改 i18n.locales(cli 建立時選的語言)切換器自動出現 / 消失、自動跟隨語言數量。

切換走 $i18n.setLocale(code):在 strategy 非 no_prefix(即 prefix / prefix_except_default,框架推薦)時,setLocale 會導航到該語言的前綴 URL(如 /en/…),hreflang / canonical 隨之正確——是 SEO 正確的整站語言切換,不是只寫 localStorage。

⚠️ 正因為真實切換會跳轉前綴路由把整個站切走語言,本頁的兩個 Demo 用預設作用域插槽做純展示、不接真實 setLocale(否則在文件站裡點一下就把文件站語言切走了)。真實的 <SwLangSwitch /> 預設用法見下方程式碼範例(不做成會跳轉的 live Demo)。

自訂能力三檔(headless 逃生艙)

按「改多少」從輕到重:

  1. 換皮膚 —— --sw-lang-switch-* CSS token(顏色 / 背景 / 圓角 / hover / 間距 / 高度 / 字級)。
  2. 換圖示 —— #icon 具名插槽傳自己圖示庫的圖示替換預設地球(作用域 { locale },僅預設 UI 生效)。
  3. 換整個互動 —— 預設作用域插槽:傳了就完全自渲染 UI,元件把 { locales, current, setLocale, canSwitch } 交給你,同時仍復用自 gate(i18n 關 / 單語言時整體渲染空,你不用自己判斷)。

基礎用法(預設「地球 + select」)

真實元件直接放進模板即可,i18n 關 / 單語言時自動不顯示。注意:以下是程式碼範例而非 live Demo——真實點擊會調 $i18n.setLocale 跳轉前綴 URL(切換整站語言),不適合在文件站裡直接跑。

<template>
  <!-- i18n 啟用且可選語言 ≥ 2 種時渲染;否則自動為空 -->
  <SwLangSwitch />
</template>

換圖示同理(#icon 覆蓋預設地球):

<script setup lang="ts">
import { PhTranslate } from '@phosphor-icons/vue'
</script>

<template>
  <SwLangSwitch>
    <template #icon><PhTranslate :size="18" /></template>
  </SwLangSwitch>
</template>

預設作用域插槽(自渲染 · 純展示)

傳預設作用域插槽即接管整個 UI,元件把歸一化後的 locales({ code, label }[])與 current(當前語言 code)交給你。下面的 Demo 僅展示這些資料:點擊只更新一個本地 demo 狀態,不呼叫作用域裡的 setLocale(避免把文件站語言切走)。

作用域插槽暴露 locales / current(點擊僅更新本地狀態,不切換)

加载中...
<script setup lang="ts">
import { ref } from 'vue'
// 展示用本地狀態;真實專案裡點擊應調作用域的 setLocale(會跳轉前綴路由)
const pick = ref('')
</script>

<template>
  <SwLangSwitch v-slot="{ locales, current }">
    <SwButton
      v-for="l in locales"
      :key="l.code"
      :class="{ 'is-current': l.code === current }"
      @click="pick = l.code"
    >
      {{ l.label }}
    </SwButton>
  </SwLangSwitch>
</template>

只讀渲染語言列表(同樣不切換,純展示 locales / current 的形狀):

只讀渲染 locales 列表 + 高亮 current

加载中...

真實專案裡,自渲染 UI 的點擊應調作用域暴露的 setLocale:

<template>
  <SwLangSwitch v-slot="{ locales, current, setLocale }">
    <button
      v-for="l in locales"
      :key="l.code"
      :aria-current="l.code === current"
      @click="setLocale(l.code)"
    >
      {{ l.label }}
    </button>
  </SwLangSwitch>
</template>

Props

名稱類型必填預設值說明
sizenumber18預設地球圖示尺寸(px)。用預設作用域插槽自渲染時不生效

Slots

名稱作用域參數說明
default{ locales, current, setLocale, canSwitch }自渲染整個切換器 UI;locales 為歸一化 { code, label }[]、current 為當前語言 code、setLocale(code) 切語言(走前綴路由)、canSwitch 恆 true(元件已據此 gate)。仍受 i18n 開且 ≥2 語言自 gate
icon{ locale }語言圖示(覆蓋預設地球,僅預設 UI 生效);locale 為當前語言 code

皮膚 Token

Token作用
--sw-lang-switch-color / --sw-lang-switch-hover-color文字 / 圖示色 / hover 色
--sw-lang-switch-bg / --sw-lang-switch-hover-bg背景 / hover 背景
--sw-lang-switch-radius圓角
--sw-lang-switch-gap / --sw-lang-switch-padding / --sw-lang-switch-height圖示與 select 間距 / 內邊距 / 高度
--sw-lang-switch-font-sizeselect 字級

注意事項

  • 自 gate 決定顯隱:i18n 關閉或只有 1 種語言時元件渲染空——不用自己寫「多語言才顯示」的條件。
  • 切換即導航:setLocale 在 prefix / prefix_except_default 策略下跳轉到前綴 URL(SEO 正確),不是純前端狀態切換;no_prefix 會丟多語言 SEO,framework 不推薦(詳見 i18n 國際化)。
  • size 僅作用於預設地球圖示:換 #icon 或預設作用域插槽自渲染時,尺寸由你自己的內容決定。
  • 無對外事件:切換直接走 $i18n.setLocale;要在語言變化後跑邏輯用 @nuxtjs/i18n 自身的 API / 路由。

相關