This commit is contained in:
oneao committed 2026-10-08 22:38:34 +08:00
1 parent f572dce2f6
commit e99a9fb274
356 files changed
+28877 -1055

No files matched your search

@@ -1,42 +1,191 @@
---
title: Button 按钮
description: 常用的操作按钮,支持多种视觉类型与状态
description: 触发一个操作,支持 8 种视觉变体、3 档尺寸与加载态
---
# Button 按钮
常用的操作按钮,支持 7 种视觉类型、3 种尺寸与加载、禁用等状态。
按钮用于触发一个即时操作。它承载「点击后发生什么」,因此同一区域里应当只有一个视觉上最重的按钮,其余操作降级表达。
## 何时使用
- 用户点击后即时触发一个动作(提交、保存、删除、导出)时使用;
- 表单、对话框、工具条的最终动作使用 `primary`(或危险动作使用 `danger`);
- 面板头部、表格行内的图标类动作使用 `type="icon"`;
- 只是页面跳转且不需要按钮外观时,直接用 `<a>`,或使用 `type="link"` 保持按钮语义。
## 基础用法
::demo{name="button/basic"}
::
不传 `type` 时使用 `primary`;按钮内容写在默认插槽里。
## 视觉类型
:::demo{name="button/basic"}
:::
语义化类型用于表达操作的风险等级。
按钮是原生 `<button>`,因此天然支持 `disabled`、键盘 `Enter / Space` 触发与表单语义。
::demo{name="button/type"}
::
## 视觉变体
`type` 决定按钮的视觉重量,请按「操作重要性」选择,而不是按颜色喜好选择。
:::demo{name="button/variant"}
:::
| 变体 | 使用场景 |
| --- | --- |
| `primary` | 页面 / 表单 / 弹窗中的**主操作**,一屏通常只有一个 |
| `secondary` | 次要操作,有底色但无主色,常用于「取消」「重置」 |
| `outline` | 与 `primary` 并排出现时的次级操作,或工具条中的常规动作 |
| `ghost` | 表格行、卡片内的低强调操作,hover 才出现底色 |
| `danger` | **不可逆**的危险操作,如删除、停用;建议配合二次确认 |
| `danger-outline` | 列表工具条中的危险动作:表达危险语义但不与 `primary` 抢视觉 |
| `link` | 视觉上是文字链接,但保留按钮的尺寸、禁用与键盘语义 |
| `icon` | 正方形描边图标按钮,用于工具条 / 面板头部动作位 |
## 尺寸
::demo{name="button/size"}
::
`size` 提供 3 档,默认 `medium`(`--g3-control-height`,32px)。
## 状态
:::demo{name="button/size"}
:::
::demo{name="button/state"}
::
尺寸只影响按钮自身的高度与字号;图标按钮(`type="icon"`)会同步变成正方形。
## 图标与撑满
## 图标
::demo{name="button/icon"}
::
使用 `#icon` 插槽放图标,图标大小跟随按钮字号(`1em`);纯图标按钮用 `type="icon"`,**必须**提供 `aria-label`,否则屏幕阅读器读不出来。
::demo{name="button/block"}
::
:::demo{name="button/icon"}
:::
`type="icon"` 的按钮没有文字,因此无障碍标签需要手动补:
```vue
<G3Button type="icon" aria-label="搜索">
<template #icon><Search /></template>
</G3Button>
```
## 加载态
`loading` 会同时做三件事:显示加载图标、进入原生 `disabled`、**拦截 `click` 事件**(不会触发 `click`),因此可以直接用它防止重复提交。
:::demo{name="button/loading"}
:::
需要注意的是:`loading` 时按钮是原生禁用状态,浏览器不会派发 `click`;组件内部也额外做了拦截,避免在「按下瞬间进入 loading」时重复触发。
## 禁用态
`disabled` 使用原生 `disabled` 属性,同时降低整体透明度并显示禁用光标。
:::demo{name="button/disabled"}
:::
禁用按钮的 `click` 不会触发,也不会被聚焦(原生行为),所以不要把「必填校验失败」的提交按钮设为禁用——用户会不知道原因。
## 撑满宽度
`block` 让按钮占满父容器宽度,常用于移动端、抽屉底部与卡片内。
:::demo{name="button/block"}
:::
## 表单中的提交与重置
`htmlType` 对应原生 `<button type>`,配合 G3Form 使用时写 `html-type="submit"` / `"reset"` 即可触发表单的提交与重置。
:::demo{name="button/html-type"}
:::
`htmlType` 默认值是 `button`,这样按钮放在表单里不会意外提交(原生 `<button>` 在表单内的默认行为是 `submit`)。
## 全局默认值
通过 `G3ConfigProvider` 的 `componentDefaults` 可以一次性修改某类组件的默认 props,组件内部的回落顺序是 **显式 prop > 全局默认值 > 组件内置默认**。
:::demo{name="button/global-defaults"}
:::
## click 事件
`@click` 回传原生 `MouseEvent`,可以直接读取修饰键或做 `preventDefault`。
:::demo{name="button/event"}
:::
## API
<ApiTable name="button" />
### Props
| 名称 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `type` | `'primary' \| 'secondary' \| 'outline' \| 'ghost' \| 'danger' \| 'danger-outline' \| 'link' \| 'icon'` | `'primary'` | 视觉变体。`icon` 为正方形描边图标按钮(无文字,需自行补 `aria-label`) |
| `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | 尺寸。对应高度 24px / 32px / 40px(`--g3-control-height-sm` / `--g3-control-height` / `--g3-control-height-lg`) |
| `htmlType` | `'button' \| 'submit' \| 'reset'` | `'button'` | 原生 `type` 属性。表单里需要提交时写 `submit` |
| `disabled` | `boolean` | `false` | 是否禁用。原生禁用,不派发 `click`,不参与焦点 |
| `loading` | `boolean` | `false` | 是否加载中。展示加载图标并**阻止 `click`**,用于防重复提交 |
| `block` | `boolean` | `false` | 是否撑满父容器宽度(`display: flex; width: 100%`) |
> `type` 与 `size` 的 prop 默认值语义上留空,以便 `ConfigProvider.componentDefaults.button` 生效;未配置全局值时回落到 `primary` / `medium`。
### Events
| 名称 | 参数 | 说明 |
| --- | --- | --- |
| `click` | `(event: MouseEvent)` | 点击按钮时触发。`disabled` 或 `loading` 时不会触发 |
### Slots
| 名称 | 参数 | 说明 |
| --- | --- | --- |
| `default` | — | 按钮文字。为空时不渲染内容容器 |
| `icon` | — | 按钮左侧图标。图标尺寸跟随字号(`1em`),加载中时会被加载图标顶到右侧 |
### 类型定义
```ts
export type ButtonType =
| 'primary'
| 'secondary'
| 'outline'
| 'ghost'
| 'danger'
| 'danger-outline'
| 'link'
| 'icon'
export type ButtonSize = 'small' | 'medium' | 'large'
export interface ButtonProps {
type?: ButtonType
size?: ButtonSize
htmlType?: 'button' | 'submit' | 'reset'
disabled?: boolean
loading?: boolean
block?: boolean
}
export interface ButtonGroupProps {
/** 排列方向,默认 horizontal */
orientation?: 'horizontal' | 'vertical'
}
```
### 样式变量
按钮只引用设计变量,换肤时覆盖同名变量即可,不需要改组件代码:
| 变量 | 默认值 | 说明 |
| --- | --- | --- |
| `--g3-control-height` | `32px` | 默认高度(`small` / `large` 用 `--g3-control-height-sm / -lg`) |
| `--g3-radius` | `6px` | 圆角 |
| `--g3-color-primary` | `#18181b` | `primary` 底色与 `link` 文字色 |
| `--g3-color-primary-on` | `#fafafa` | `primary` 上的文字色 |
| `--g3-color-danger` | `#ec4246` | `danger` / `danger-outline` 的红 |
| `--g3-fill` / `--g3-fill-hover` | `rgba(0,0,0,.04 / .08)` | `secondary` / `ghost` / `icon` 的底色 |
## 设计说明
- **hover 去抖**:按钮的「离开 hover」过渡带 60ms 延迟,用来吸收鼠标在按钮边缘反复进出造成的背景闪烁;「进入 hover」延迟为 0,保证跟手。
- **按下反馈**:`:active` 时 `transform: scale(0.97)`,加载态会压掉缩放,避免「进行中」的按钮抖动。
- **禁用态**:整体 `opacity: .5`,保留原配色,不再改文字颜色——这样深浅主题下都能看出是同一个按钮。