shadcn-vue Switch 组件完全指南安装、用法、表单集成与源码解析【免费下载链接】shadcn-vueVue port of shadcn-ui项目地址: https://gitcode.com/gh_mirrors/sh/shadcn-vue导读Switch开关是表单与设置面板中最常用的切换控件允许用户在「已选中」与「未选中」两种状态之间切换。本指南基于 shadcn-vue 仓库中的官方文档 deprecated/www/src/content/docs/components/switch.md 展开结合仓库内 Switch 组件的真实源码apps/v4/registry/bases/reka/ui/switch/Switch.vue与各风格示例系统讲解如何安装、导入、使用 Switch如何在滑块thumb内嵌入图标以及如何将 Switch 集成进 VeeValidate Zod 的表单体系。读完本文你将掌握 Switch 组件的全部常见用法并能根据需求自行扩展尺寸、样式与无障碍行为。组件概览Switch 是一个受控/非受控皆可的布尔切换控件底层基于 Reka UI 的SwitchRoot与SwitchThumb原语构建。它具备以下开箱即用的能力双状态切换checked / unchecked通过model-value与update:model-value事件完成受控绑定键盘与焦点支持focus-visible态样式内置支持 Tab 聚焦与空格/回车切换无障碍内部由 Reka UI 处理roleswitch、aria-checked等语义属性并可透传id、aria-label等属性禁用状态disabled时禁用点击并降低透明度opacity-50插槽扩展thumb插槽允许在滑块内渲染自定义内容如图标、加载态。从文档 frontmatter 可以确认的信息官方文档的 frontmatter 明确了组件的定位与技术来源--- title: Switch description: A control that allows the user to toggle between checked and not checked. source: apps/www/src/registry/default/ui/switch primitive: https://www.reka-ui.com/docs/components/switch.html ---source指向组件源码目录即仓库中的 deprecated/www/src/registry/default/ui/switch当前 v4 版本对应 apps/v4/registry/bases/reka/ui/switchprimitive标明其基础原语来自 Reka UI 的 Switch 组件shadcn-vue 负责在其之上做样式与 DX 封装。安装官方文档提供了两种安装方式CLI 一键安装与手动安装。方式一CLI 安装推荐在项目根目录执行npx shadcn-vuelatest add switchCLI 会自动完成以下工作解析当前项目已有的 shadcn-vue 配置将 Switch 组件源码Switch.vue与index.ts复制到项目的components/ui/switch目录自动安装运行时依赖reka-ui如尚未安装将组件注册到项目的组件索引中使其可被自动导入。仓库中index.ts的导出方式deprecated/www/src/registry/default/ui/switch/index.ts验证了最终安装形态export { default as Switch } from ./Switch.vue方式二手动安装如果你希望完全掌控代码或项目不便使用 CLI可按官方文档的步骤手动安装。第一步安装运行时依赖npm install reka-uireka-ui是 Switch 的底层原语库提供SwitchRoot、SwitchThumb、SwitchRootProps、SwitchRootEmits等核心导出。第二步复制组件代码将以下源码复制到项目的components/ui/switch/Switch.vue以 v4 的 new-york 风格为例完整文件见 apps/v4/registry/new-york-v4/ui/switch/Switch.vuescript setup langts import type { SwitchRootEmits, SwitchRootProps } from reka-ui import type { HTMLAttributes } from vue import { reactiveOmit } from vueuse/core import { SwitchRoot, SwitchThumb, useForwardPropsEmits, } from reka-ui import { cn } from /lib/utils const props definePropsSwitchRootProps { class?: HTMLAttributes[class] }() const emits defineEmitsSwitchRootEmits() const delegatedProps reactiveOmit(props, class) const forwarded useForwardPropsEmits(delegatedProps, emits) /script template SwitchRoot v-slotslotProps >script setup langts import { Switch } from /components/ui/switch /script template Switch / /template官方文档给出的首个示例即是这种最简形式——不带任何属性使用非受控模式点击后内部自动维护状态。与 Label 组合使用实际界面中开关几乎总是配有一个文字说明。推荐将Switch与Label组合通过id/for建立关联对应演示组件 apps/v4/components/demo/SwitchDemo.vue 与 deprecated/www/src/registry/default/examples/SwitchDemo.vuescript setup langts import { Label } from /components/ui/label import { Switch } from /components/ui/switch /script template div classflex items-center space-x-2 Switch idairplane-mode / Label forairplane-modeAirplane Mode/Label /div /templateid与for的关联带来两个直接收益点击命中区域扩大点击 Label 文字也能切换开关无障碍提升屏幕阅读器会将文字与开关状态正确关联。受控模式与 v-modelSwitch 完全遵循 Vue 的model-value/update:model-value约定因此支持v-model直接绑定script setup langts import { ref } from vue import { Switch } from /components/ui/switch const isDark ref(false) /script template Switch v-modelisDark / /template也可以显式传入model-value并监听update:model-value事件实现自定义逻辑。该事件类型来自 Reka UI 的SwitchRootEmits在组件源码中通过defineEmitsSwitchRootEmits()透传见 apps/v4/registry/bases/reka/ui/switch/Switch.vue。默认选中非受控模式下可通过default-checked设置初始选中状态这在仓库示例中频繁出现例如 apps/v4/registry/bases/reka/examples/switch/SwitchDisabled.vue 中的禁用默认选中组合Switch idswitch-disabled-checked :default-checkedtrue :disabledtrue /在滑块内添加图标官方文档单独用一个章节介绍了「在 Switch 滑块内添加图标」的进阶用法核心是使用#thumb插槽。以明暗主题切换为例template Switch :model-valueisDark update:model-valuetoggleTheme template #thumb Icon v-ifisDark iconlucide:moon classsize-3 / Icon v-else iconlucide:sun classsize-3 / /template /Switch /template这段代码同时展示了三个要点受控绑定isDark决定开关状态toggleTheme响应状态变化并切换主题插槽内容响应状态图标根据当前主题动态切换——暗色显示月亮、亮色显示太阳图标尺寸控制通过classsize-3控制图标在滑块内的显示大小。从源码看thumb插槽由SwitchThumb渲染见 apps/v4/registry/new-york-v4/ui/switch/Switch.vue 中的slot namethumb v-bindslotProps /并将slotProps一并透传给插槽内容因此在插槽内可以访问到 Reka UI 提供的开关状态数据。尺寸与禁用等扩展用法v4 版本的 Switch 在基础组件上额外提供了size属性sm | default源码见 apps/v4/registry/bases/reka/ui/switch/Switch.vueconst props withDefaults(definePropsSwitchRootProps { class?: HTMLAttributes[class] size?: sm | default }(), { size: default, })尺寸通过data-size属性传递到根元素SwitchRoot>div classflex items-center gap-2 Switch idswitch-size-sm sizesm / Label html-forswitch-size-smSmall/Label /div div classflex items-center gap-2 Switch idswitch-size-default sizedefault / Label html-forswitch-size-defaultDefault/Label /div禁用状态通过:disabledtrue即可禁用开关禁用后不可点击样式上自动降低透明度disabled:opacity-50。仓库示例 apps/v4/registry/bases/reka/examples/switch/SwitchDisabled.vue 同时覆盖了「禁用且未选中」与「禁用且默认选中」两种场景Switch idswitch-disabled-unchecked :disabledtrue / Switch idswitch-disabled-checked :default-checkedtrue :disabledtrue /带描述的布局在表单或设置页中开关常与标题、描述文字并列展示。可以借助Field系列组件Field、FieldContent、FieldTitle、FieldDescription、FieldLabel实现规整的横向布局参考 apps/v4/registry/bases/reka/examples/switch/SwitchWithDescription.vueFieldLabel html-forswitch-focus-mode Field orientationhorizontal FieldContent FieldTitleShare across devices/FieldTitle FieldDescription Focus is shared across devices, and turns off when you leave the app. /FieldDescription /FieldContent Switch idswitch-focus-mode / /Field /FieldLabel在表单中使用VeeValidate Zod官方文档的 Examples 章节给出了「Form」示例对应仓库中的 deprecated/www/src/registry/default/examples/SwitchForm.vue。该示例演示了 Switch 与vee-validate、zod的完整集成是设置页「邮件通知」类场景的典型模板。定义表单 Schemaimport { toTypedSchema } from vee-validate/zod import { useForm } from vee-validate import * as z from zod const formSchema toTypedSchema(z.object({ marketing_emails: z.boolean().default(false).optional(), security_emails: z.boolean(), }))marketing_emails可选布尔默认falsesecurity_emails必填布尔。初始化表单const { handleSubmit } useForm({ validationSchema: formSchema, initialValues: { security_emails: true, }, })initialValues给security_emails设置了初始值true对应界面上该开关默认处于开启状态。提交逻辑const onSubmit handleSubmit((values) { toast({ title: You submitted the following values:, description: h(pre, { class: mt-2 w-[340px] rounded-md bg-slate-950 p-4 }, h(code, { class: text-white }, JSON.stringify(values, null, 2))), }) })提交时把表单值 JSON 序列化后通过 toast 展示方便验证开关状态是否正确绑定。模板中的绑定方式每个开关字段通过FormField的value与handleChange完成受控绑定FormField v-slot{ value, handleChange } namemarketing_emails FormItem classflex flex-row items-center justify-between rounded-lg border p-4 div classspace-y-0.5 FormLabel classtext-base Marketing emails /FormLabel FormDescription Receive emails about new products, features, and more. /FormDescription /div FormControl Switch :model-valuevalue update:model-valuehandleChange / /FormControl /FormItem /FormField第二个字段security_emails还展示了「表单中的只读开关」写法Switch :model-valuevalue disabled aria-readonly update:model-valuehandleChange /即通过disabled禁止用户操作、同时用aria-readonly向辅助技术声明该字段只读但仍保留表单字段语义。整个表单由form classw-full space-y-6 submitonSubmit包裹配合提交按钮即可构成完整的通知偏好设置页。源码实现解析Switch 组件的核心价值在于用最薄的封装把 Reka UI 原语的能力完整透传同时注入 shadcn-vue 的设计系统样式。以 v4 bases 风格实现apps/v4/registry/bases/reka/ui/switch/Switch.vue为例关键点有三Props 合并透传SwitchRootPropsReka UI 的根组件属性classsize共同组成组件的对外 Props运行时通过reactiveOmit(props, class, size)剔除样式类与尺寸字段后用useForwardPropsEmits统一转发给SwitchRootEmits 原样转发SwitchRootEmits直接透传保证update:model-value等事件与 Reka UI 语义一致样式注入与状态钩子根元素上的data-[statechecked]:/data-[stateunchecked]:系列类直接响应 Reka UI 内部维护的状态属性实现选中/未选中两种视觉态data-disabled:系列类则接管禁用态的视觉反馈。new-york 风格apps/v4/registry/new-york-v4/ui/switch/Switch.vue在实现上完全一致仅样式 token 与尺寸不同如h-[1.15rem] w-8、size-4的滑块、translate-x-[calc(100%-2px)]的位移。这也正是 shadcn-vue 的架构特点同一套原语逻辑通过替换样式类即可切换视觉风格。状态样式对照状态根元素样式new-york效果checkeddata-[statechecked]:bg-primary轨道填充主题色uncheckeddata-[stateunchecked]:bg-input暗色下bg-input/80轨道使用输入框底色聚焦focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-3焦点环提示禁用disabled:cursor-not-allowed disabled:opacity-50禁止点击 半透明滑块位移滑块SwitchThumb通过data-[statechecked]:translate-x-[calc(100%-2px)]实现从左侧到右侧的平滑位移——100%是滑块自身宽度减去 2px 边框留白后恰好落到轨道右侧边缘transition-transform保证位移动画平滑。总结Switch 组件是 shadcn-vue 中「薄封装 完整透传」设计哲学的典型代表安装npx shadcn-vuelatest add switch一条命令即可也可手动安装reka-ui后复制组件代码用法支持最简非受控模式、v-model受控模式、#thumb图标插槽、尺寸与禁用等扩展表单集成通过FormField的value/handleChange与 VeeValidate Zod 无缝协作底层原理所有交互逻辑由 Reka UI 原语承担shadcn-vue 层只负责样式注入与 Props/Emits 透传。相关资源可继续深入阅读官方文档 deprecated/www/src/content/docs/components/switch.md、v4 基础组件源码 apps/v4/registry/bases/reka/ui/switch/Switch.vue、表单示例 deprecated/www/src/registry/default/examples/SwitchForm.vue以及各风格的示例集合见 apps/v4/registry/bases/reka/examples/switch。【免费下载链接】shadcn-vueVue port of shadcn-ui项目地址: https://gitcode.com/gh_mirrors/sh/shadcn-vue创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
