# Switch · HeroUI

> Switch 从 HeroUI v2 到 v3 的迁移指南。

- 页面: https://jiguang132.com/zh/systems/heroui/docs/migration/switch
- 改编自: HeroUI 文档 (Apache-2.0) @ 60edd8ed751b1d2a270623fbb182bbcfa8baa9af

> 
  完整的 API 参考、样式指南与高级示例请参阅 [v3 Switch 文档](/systems/heroui/docs/components/switch)。本指南只关注从 HeroUI v2 的迁移。


## 结构变化

在 v2 中，`Switch` 结构简单，children 作为标签：

```tsx
import { Switch } from "@heroui/react";

export default function App() {
  return <Switch>Enable notifications</Switch>;
}
```

在 v3 中，`Switch` 需要复合组件：

```tsx
import { Switch, Label } from "@heroui/react";

export default function App() {
  return (
    <Switch>
      <Switch.Content>
        <Switch.Control>
          <Switch.Thumb />
        </Switch.Control>
        Enable notifications
      </Switch.Content>
    </Switch>
  );
}
```

## 主要变化

### 1. 组件结构

**v2：** children 作为标签的简单 Switch  
**v3：** 复合组件（`Switch.Content`、`Switch.Control`、`Switch.Thumb`）与 `Label` 组件

### 2. Prop 变更

| v2 prop | v3 位置 | 说明 |
| ------- | ------- | ---- |
| `onValueChange` | `onChange` | 事件处理函数已重命名 |
| `size` | `size` | 仍在根上（`sm` \| `md` \| `lg`） |
| `label` | — | 请使用 `Label` 组件 |
| `color` | — | 已移除（请使用 Tailwind CSS） |
| `thumbIcon` | — | 请在 `Switch.Thumb` 内使用 `Switch.Icon` |
| `startContent` | — | 请直接自定义控件 |
| `endContent` | — | 请直接自定义控件 |
| `classNames` | — | 请在各子组件上使用 `className` |
| `disableAnimation` | — | 已移除（动画机制已不同） |

### 3. 新组件

- `SwitchGroup` — 用于将多个 Switch 成组  
- `Switch.Content` — 可点击的标签，包裹控件与 `Label`  
- `Switch.Icon` — 拇指（Thumb）内的图标  

## 迁移示例

### 受控 Switch


  

#### v2


    ```tsx
    import { useState } from "react";

    const [isSelected, setIsSelected] = useState(true);

    <Switch isSelected={isSelected} onValueChange={setIsSelected}>
      Airplane mode
    </Switch>
    ```
  
  

#### v3


    ```tsx
    import { useState } from "react";

    const [isSelected, setIsSelected] = useState(true);

    <Switch isSelected={isSelected} onChange={setIsSelected}>
      <Switch.Content>
        <Switch.Control>
          <Switch.Thumb />
        </Switch.Control>
        Airplane mode
      </Switch.Content>
    </Switch>
    ```
  


### 无标签


  

#### v2


    ```tsx
    <Switch defaultSelected aria-label="Automatic updates" />
    ```
  
  

#### v3


    ```tsx
    <Switch defaultSelected aria-label="Automatic updates">
      <Switch.Content>
        <Switch.Control>
          <Switch.Thumb />
        </Switch.Control>
      </Switch.Content>
    </Switch>
    ```
  


### 带拇指图标


  

#### v2


    ```tsx
    <Switch thumbIcon={<CheckIcon />}>Enable notifications</Switch>
    ```
  
  

#### v3


    ```tsx
    <Switch>
      <Switch.Content>
        <Switch.Control>
          <Switch.Thumb>
            <Switch.Icon>
              <CheckIcon />
            </Switch.Icon>
          </Switch.Thumb>
        </Switch.Control>
        Enable notifications
      </Switch.Content>
    </Switch>
    ```
  


### 带起始 / 结束内容


  

#### v2


    ```tsx
    <Switch
      startContent={<SunIcon />}
      endContent={<MoonIcon />}
    >
      Dark mode
    </Switch>
    ```
  
  

#### v3


    ```tsx
    <Switch>
      <Switch.Content>
        <Switch.Control className="flex items-center gap-2">
          <SunIcon />
          <Switch.Thumb />
          <MoonIcon />
        </Switch.Control>
        Dark mode
      </Switch.Content>
    </Switch>
    ```
  


### 带标签与描述


  

#### v2


    ```tsx
    <Switch description="You will receive notifications for all activity">
      Enable notifications
    </Switch>
    ```
  
  

#### v3


    ```tsx
    import { Switch, Label, Description } from "@heroui/react";

    <Switch>
      <Switch.Content>
        <Switch.Control>
          <Switch.Thumb />
        </Switch.Control>
        Enable notifications
      </Switch.Content>
      <Description>You will receive notifications for all activity</Description>
    </Switch>
    ```
  


### 尺寸与颜色


  

#### v2


    ```tsx
    {/* Sizes */}
    <div className="flex gap-4">
      <Switch size="sm">Small</Switch>
      <Switch size="md">Medium</Switch>
      <Switch size="lg">Large</Switch>
    </div>
    
    {/* Colors */}
    <Switch color="primary">Primary</Switch>
    <Switch color="success">Success</Switch>
    <Switch color="danger">Danger</Switch>
    ```
  
  

#### v3


    ```tsx
    {/* Sizes */}
    <div className="flex gap-4">
      <Switch size="sm">
        <Switch.Content>
          <Switch.Control>
            <Switch.Thumb />
          </Switch.Control>
          Small
        </Switch.Content>
      </Switch>
      <Switch size="md">
        <Switch.Content>
          <Switch.Control>
            <Switch.Thumb />
          </Switch.Control>
          Medium
        </Switch.Content>
      </Switch>
      <Switch size="lg">
        <Switch.Content>
          <Switch.Control>
            <Switch.Thumb />
          </Switch.Control>
          Large
        </Switch.Content>
      </Switch>
    </div>
    
    {/* Colors - Use Tailwind CSS classes */}
    <Switch>
      <Switch.Content>
        <Switch.Control className="data-[selected=true]:bg-accent">
          <Switch.Thumb />
        </Switch.Control>
        Primary
      </Switch.Content>
    </Switch>
    <Switch>
      <Switch.Content>
        <Switch.Control className="data-[selected=true]:bg-success">
          <Switch.Thumb />
        </Switch.Control>
        Success
      </Switch.Content>
    </Switch>
    <Switch>
      <Switch.Content>
        <Switch.Control className="data-[selected=true]:bg-danger">
          <Switch.Thumb />
        </Switch.Control>
        Danger
      </Switch.Content>
    </Switch>
    ```
  


### Switch 组


  

#### v2


    ```tsx
    {/* No built-in group component in v2 */}
    <div className="flex flex-col gap-2">
      <Switch name="notifications">Allow Notifications</Switch>
      <Switch name="marketing">Marketing emails</Switch>
    </div>
    ```
  
  

#### v3


    ```tsx
    import { SwitchGroup } from "@heroui/react";

    <SwitchGroup>
      <Switch name="notifications">
        <Switch.Content>
          <Switch.Control>
            <Switch.Thumb />
          </Switch.Control>
          Allow Notifications
        </Switch.Content>
      </Switch>
      <Switch name="marketing">
        <Switch.Content>
          <Switch.Control>
            <Switch.Thumb />
          </Switch.Control>
          Marketing emails
        </Switch.Content>
      </Switch>
    </SwitchGroup>
    ```
  


## 组件组成

v3 `Switch` 的结构如下：

```
Switch (Root)
  ├── Switch.Content (the clickable label)
  │   ├── Switch.Control
  │   │   └── Switch.Thumb
  │   │       └── Switch.Icon (optional)
  │   └── Label
  ├── Description (optional, sibling)
  └── FieldError (optional, sibling)
```

分组时：

```
SwitchGroup
  ├── Switch
  │   ├── Switch.Content
  │   │   ├── Switch.Control
  │   │   │   └── Switch.Thumb
  │   │   └── Label
  │   └── Description (optional)
  └── Switch
      ├── Switch.Content
      │   ├── Switch.Control
      │   │   └── Switch.Thumb
      │   └── Label
      └── Description (optional)
```

## 说明

### 事件处理函数

- **v2：** `onValueChange` prop  
- **v3：** `onChange` prop（签名相同：`(isSelected: boolean) => void`）

### 标签

- **v2：** children 作为标签  
- **v3：** `Label` 放在 `Switch.Content`（可点击的标签）内；`Description` / `FieldError` 作为 `Switch.Content` 的同级元素

### 图标

- **v2：** `thumbIcon` 用于拇指内图标，`startContent` / `endContent` 用于外侧图标  
- **v3：** 拇指内图标用 `Switch.Icon`（置于 `Switch.Thumb` 内）；起始 / 结束内容请自定义 `Switch.Control`

## 总结

1. **组件结构**：必须使用复合组件（`Switch.Content`、`Switch.Control`、`Switch.Thumb`）
2. **可点击的标签**：用 `Switch.Content` 包裹 `Switch.Control` 与 `Label`；将 `Description` / `FieldError` 作为 `Switch.Content` 的同级元素
3. **标签**：不再用 children 作为标签 — 请在 `Switch.Content` 内使用 `Label`
4. **事件处理函数**：`onValueChange` → `onChange`
5. **样式相关 prop 已移除**：`color` — 请使用 Tailwind CSS
6. **图标相关 prop 已移除**：`thumbIcon`、`startContent`、`endContent` — 请用子组件或直接自定义
7. **`classNames` 已移除**：请在各子组件上使用 `className` prop
8. **新组件**：`SwitchGroup` 用于成组；`Switch.Content` 作为可点击的标签，包裹控件与 `Label`

---

JGuang 全部资源索引: https://jiguang132.com/llms.txt
