v0.1.9

Switch 开关

引入import { Switch } from '@apollo-design/ui';

开关选择器。

何时使用

  • 需要表示开 / 关两种状态,且切换后立即生效(不需要点「确定」)。
  • 与复选框的区别:开关的语义是「立即生效的状态」,复选框是「待提交的选择」。

代码演示

加载中…

基本 #

最简单的用法:defaultChecked 非受控;@change 回调收到 (checked, event)。

加载中…

不可用 #

disabled 让开关失效;loading 同样会强制失效(内部是 || 判据)。

加载中…

加载中 #

loading 表示正在加载:把手位置显示一个转圈图标,并强制不可交互。

加载中…

尺寸 #

size="small" 得到小号开关;size="default" 已废弃(会提示改用 "medium")。

加载中…

文字和图标 #

checkedChildren / unCheckedChildren 接受字符串、数字或任意节点(含图标)。

加载中…

语义化样式 #

通过 classNames / styles 自定义三槽(root / content / indicator);两者都支持对象与 函数两种形态,函数形态能拿到合并后的 props(如 size)。

最后一个开关从 ConfigProvider.components.switch 读取根样式和语义配置,切换时函数样式会随当前 checked 更新。

加载中…

组件 Token #

通过 ConfigProvider.theme.components.Switch 覆盖组件 Token;当前配置会写入开关根元素的 CSS 变量,由静态样式消费。支持主题切换、嵌套覆盖和撤销。

覆盖 trackHeight / trackMinWidth / trackPadding / handleSize / handleBg / handleShadow 后的效果(把手比轨道大,探出轨道外)。

见 demo/(7 个,覆盖 antd 的主要用户场景)。

API

参数 说明 类型 默认值
checked 指定当前是否选中(受控) boolean —
defaultChecked 初始是否选中(非受控) boolean false
value ⚠️ checked 的别名(antd @since 5.12.0) boolean —
defaultValue ⚠️ defaultChecked 的别名 boolean —
onChange change 事件的监听器写法(两个参数;disabled 时不触发) (checked: boolean, event: MouseEvent | KeyboardEvent) => void —
onClick 原生 click 事件监听器;状态从 change / v-model 获取 (event: MouseEvent) => void —
checkedChildren 选中时的内容 VNodeChild —
unCheckedChildren 未选中时的内容 VNodeChild —
disabled 失效状态 boolean —
loading 加载中;⚠️ 会强制失效(|| 判据) boolean false
size 尺寸;⚠️ 'default' 已废弃(提示改用 'medium') 'small' | 'medium' | 'middle' | 'default' —
autoFocus 自动获取焦点 boolean —
title / id / tabIndex 原生属性(落 <button>) — —
class / style 根元素原生 attrs(不是 Props) — —
classNames / styles 语义槽 { root, content, indicator }(对象或函数) — —

checked 优先于 value;defaultChecked 优先于 defaultValue,默认值只用于初始化。受控交互只提出更新,显示状态由父级回传决定;撤销两个受控值后保留最后已接受的状态。

Slots

插槽 说明
checkedChildren 选中内容;存在时优先于同名 prop,包括有意为空的内容
unCheckedChildren 未选中内容;存在时优先于同名 prop,包括有意为空的内容

插槽内容会随当前渲染更新;条件插槽消失时恢复同名 prop。支持文本、数字(含 0)、VNode 和数组。

ConfigProvider

components.switch 支持 SwitchConfig 的 className、style、classNames 和 styles。同一区域的类名拼接,样式按 Provider styles → Provider 根 style → 组件 styles → 原生根 style 合并,后者优先;配置替换和撤销会即时生效。

未指定的 disabled 和 size 分别跟随 componentDisabled、componentSize。全局 large 使用 Switch 的常规 medium 尺寸;显式组件 prop 优先,loading 始终禁用交互。语义函数读取当前解析后的 size 和 disabled。

Events

事件 说明 参数
update:checked v-model:checked 通道(与 onChange 同时发出) boolean
update:value v-model:value 通道(别名通道,同上) boolean
change 声明的 Vue 语义事件;每次点击或方向键更新时发送一次,disabled 时不发送 (checked: boolean, event: MouseEvent | KeyboardEvent)
click 原生按钮点击,含键盘激活;方向键不合成点击 MouseEvent

@change 与 onChange 注册同一事件,不会额外监听原生 DOM change。@click 只接收原生 MouseEvent,支持 .stop / .prevent / .once;不再传旧 (checked, event),无兼容层或弃用期。迁移状态读取到 @change 或 v-model:checked。

原生根 style 支持字符串、对象和数组,与语义 root 样式按 Vue 规则合并;调用方样式优先。 原生小写 tabindex / autofocus 同样落在按钮;同时提供时,显式 tabIndex / autoFocus prop 优先。

键盘

按键 行为
ArrowLeft 置为未选中(disabled 时不生效)
ArrowRight 置为选中(disabled 时不生效)
Space / Enter 原生 <button> 的激活行为(等价点击)

方向键使用标准 KeyboardEvent.key 并阻止滚动;Space/Enter 交由按钮原生激活,只产生一次 click 和状态变更。

Ref

名称 类型
nativeElement HTMLButtonElement | null
focus / blur (options?: FocusOptions) => void / () => void

⚠️ antd 的 ref 直接是 HTMLButtonElement;本仓按组件库惯例暴露对象 (迁移时 ref.current.focus() → ref.value.focus())。

Theme(Component Token)

13 个,与 antd 的 ComponentToken 逐字段对齐(CSS 变量形态 --apollo-switch-*)。

Token 说明 默认值
trackHeight 开关高度 22px
trackHeightSM 小号开关高度 16px
trackMinWidth 开关最小宽度 44px
trackMinWidthSM 小号开关最小宽度 28px
trackPadding 开关内边距 2px
handleBg 把手背景色 #fff
handleShadow 把手阴影 0 2px 4px 0 rgba(0,35,11,0.2)
handleSize 把手大小 18px
handleSizeSM 小号把手大小 12px
innerMinMargin 内容区最小边距 9px
innerMaxMargin 内容区最大边距 24px
innerMinMarginSM 小号内容区最小边距 6px
innerMaxMarginSM 小号内容区最大边距 18px

这 13 项通过 ConfigProvider.theme.components.Switch 配置,数字长度自动补 px,也支持 CSS 长度字符串。没有字段覆盖时从当前全局主题派生;嵌套主题只覆盖指定字段,配置替换和撤销会更新现有按钮。旧 D50「组件 Token 不随主题更新」已修正,静态 CSS 仍保留默认值。

<ConfigProvider :theme="{ components: { Switch: { trackHeight: 14, handleSize: 20 } } }">
  <Switch aria-label="自定义开关" />
</ConfigProvider>

主题变量先于 Provider 样式、组件语义根样式和原生根 style 合并;可以通过这些根样式覆盖相应 CSS 变量。自定义 prefixCls 时组件变量使用当前前缀;仍须提供对应静态 CSS。

FAQ

禁用时点击会触发吗? 真实用户交互及按钮的原生 .click() 由浏览器抑制,不发 click/change/update。显式 dispatchEvent 仍是普通 DOM 派发:监听器收到原生事件,但不会改变禁用状态或发送 change/update。

value 和 checked 有什么区别? 没有区别 —— value / defaultValue 是 checked / defaultChecked 的别名 (antd 5.12.0 起为表单场景加的)。两者同时传时 checked 优先。

Powered by Vue 3 + ViteApollo Design · Vue NativeGitHub