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 逃生舱)
按「改多少」从轻到重:
- 换皮肤 ——
--sw-lang-switch-*CSS token(颜色 / 背景 / 圆角 / hover / 间距 / 高度 / 字号)。 - 换图标 ——
#icon具名插槽传自己图标库的图标替换默认地球(作用域{ locale },仅默认 UI 生效)。 - 换整个交互 —— 默认作用域插槽:传了就完全自渲染 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
| 名称 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
size | number | 18 | 默认地球图标尺寸(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-size | select 字号 |
注意事项
- 自 gate 决定显隐:i18n 关闭或只有 1 种语言时组件渲染空——不用自己写「多语言才显示」的条件。
- 切换即导航:
setLocale在prefix/prefix_except_default策略下跳转到前缀 URL(SEO 正确),不是纯前端状态切换;no_prefix会丢多语言 SEO,framework 不推荐(详见 i18n 国际化)。 size仅作用于默认地球图标:换#icon或默认作用域插槽自渲染时,尺寸由你自己的内容决定。- 无对外事件:切换直接走
$i18n.setLocale;要在语言变化后跑逻辑用@nuxtjs/i18n自身的 API / 路由。