Appearance
Button 按钮
按钮用于触发即时操作,是业务界面里最常见的动作入口。
何时使用
- 触发提交、保存、删除、打开弹层等即时动作。
- 在操作区表达主次关系、危险程度和加载反馈。
- 多个相关动作需要组成按钮组时。
基础用法
vue
<template>
<x-button>默认按钮</x-button>
<x-button type="primary">主要按钮</x-button>
<x-button type="outline">描边按钮</x-button>
<x-button type="text">文本按钮</x-button>
</template>外部水波纹
vue
<template>
<x-button>默认水波纹</x-button>
<x-button type="primary">主要水波纹</x-button>
<x-button status="danger">危险水波纹</x-button>
<x-button loading>加载不触发</x-button>
<x-button disabled>禁用不触发</x-button>
</template>Button 默认开启类似 Ant Design Vue 的外部轮廓水波纹。disabled、loading、link 和 type="text" 状态不会展示外部水波纹。
状态
vue
<template>
<x-button status="default">默认</x-button>
<x-button status="success">成功</x-button>
<x-button status="warning">警告</x-button>
<x-button status="strong">强调</x-button>
<x-button status="danger">危险</x-button>
<x-button status="info">信息</x-button>
<x-button disabled>禁用</x-button>
</template>状态色实心按钮
五种状态色都提供实心(高亮)形态,统一使用白字与主题惯例一致。实心底色即主题种子色:主要 #1c61ff、成功 #00a809、警告 #ffb800、强调 #ff8200、危险 #e02225。
危险色种子 #e02225 的白字对比为 4.75:1,实心底直接使用种子本身,不再需要压暗变体。
vue
<template>
<x-button type="primary">主要</x-button>
<x-button type="primary" status="success">成功</x-button>
<x-button type="primary" status="warning">警告</x-button>
<x-button type="primary" status="strong">强调</x-button>
<x-button type="primary" status="danger">危险</x-button>
</template>实心底与白字在明暗主题下都恒定不翻转,因此暗色下仍是同一块强调色。更换主题种子色(base.scss 的 --x-color-<name>)后实心按钮整体联动。
亮黄色、亮橙色实底上的白字属于主题惯例内的折中:这类底亮度过高,强行让白字达到正文级 4.5:1 只能压深到底色失去品牌识别。参考 Arco 的橙色实底白字为 2.57:1、Ant Design 的 warning 为 1.90:1,本库 warning / strong 与二者处于同一水平。需要更高可读性时,可改用 type="outline"、plain 或 type="text" 形态,或把种子色选得更深。各状态实测值与回归下限由 script/check-contrast.js 守护。
类型与边框
vue
<template>
<x-button type="dashed">虚线按钮</x-button>
<x-button type="outline">线性按钮</x-button>
<x-button type="text">文本按钮</x-button>
<x-button plain status="success">朴素成功</x-button>
<x-button :border="false" status="danger">无边框危险</x-button>
<x-button link>链接按钮</x-button>
</template>border="false" 使用弱背景状态色,不会切换成实心危险按钮。需要实心危险按钮时使用 type="primary" status="danger"。
彩色文字按钮(plain、outline、text、link)的文字色就是品牌主色(与实心按钮、Link、Tag 同源),不做压暗处理——这是 Arco 的做法:状态文字即主色,一眼可辨、色系统一。对比度下限对齐 Arco 同级角色(而非通用 4.5:1 正文标准),由 script/check-contrast.js 的 ARCO_BASELINE 守护。
交互三态
按钮的常态、悬浮、按下按渐深梯度设计,每一级都可感知且保持轻盈(明度差 ≥ 0.025,由门禁守护):
| 形态 | 常态 | 悬浮 | 按下 |
|---|---|---|---|
| 默认 / 信息(灰色系) | fill-2 | neutral-3 | neutral-4 |
| 彩色弱底 / 描边 / 文本 | 无色或同色浅底(0%) | 混入按钮文字色 10% | 混入按钮文字色 16% |
| 实色 | 种子实底 | 混白 8%(更亮) | 混恒定深 10%(更深) |
默认按钮不用 fill-2/3/4 递进:全局 fill 灰阶在浅端被压缩,fill-2 与 fill-3 只差 3 个通道,悬浮态几乎看不出变化;改用 neutral-3/4 后与 Arco 的步进一致。
状态矩阵
vue
<template>
<x-button status="danger">弱危险</x-button>
<x-button type="primary" status="danger">实心危险</x-button>
<x-button type="outline" status="danger">描边危险</x-button>
<x-button type="dashed" status="danger">虚线危险</x-button>
<x-button type="text" status="danger">文本危险</x-button>
<x-button :border="false" status="danger">无边框危险</x-button>
</template>Button 的状态色基于组件 alias token 组织,例如 --x-button-color-bg-danger-subtle、--x-button-color-bg-danger-solid、--x-button-color-text-danger。后续自定义主题可以优先覆盖这些组件级 token。
形状
vue
<template>
<x-button shape="round">圆角</x-button>
<x-button shape="circle">圆</x-button>
<x-button shape="square">直角</x-button>
<x-button shape="circle" type="primary">+</x-button>
</template>尺寸
vue
<template>
<x-button size="mini">迷你</x-button>
<x-button size="small">小型</x-button>
<x-button size="medium">中型</x-button>
<x-button size="large">大型</x-button>
<x-button size="huge">超大</x-button>
</template>加载与事件
vue
<template>
<x-button :loading="loading" type="primary" @click="runAsync">异步提交</x-button>
<x-button :debounce="800" @click="pushLog('debounce')">防重复点击</x-button>
<x-button loading @click="pushLog('loading')">加载中</x-button>
<x-button disabled @click="pushLog('disabled')">禁用按钮</x-button>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const loading = ref(false);
const logs = ref<string[]>([]);
const runAsync = () => {
loading.value = true;
logs.value = ['async start', ...logs.value];
window.setTimeout(() => {
loading.value = false;
logs.value = ['async done', ...logs.value];
}, 1200);
};
const pushLog = (label: string) => {
logs.value = [`${label} clicked`, ...logs.value];
};
</script>原生表单类型
vue
<template>
<form @submit.prevent="handleSubmit">
<x-button type="primary" html-type="submit">提交表单</x-button>
<x-button html-type="reset">重置</x-button>
<x-button>普通按钮</x-button>
</form>
</template>
<script setup lang="ts">
const handleSubmit = () => {
// 处理已经通过原生 submit 事件提交的数据
};
</script>type 控制视觉样式,html-type 控制原生按钮行为。默认 html-type="button",不会因为放进表单而意外提交。
插槽内容
vue
<template>
<x-button type="primary">
<template #prefix>
<span aria-hidden="true">+</span>
</template>
新建
</x-button>
<x-button>
导出
<template #suffix>
<span aria-hidden="true">↓</span>
</template>
</x-button>
<x-button shape="circle">
<template #icon>
<span aria-hidden="true">?</span>
</template>
</x-button>
</template>宽度与窄按钮
vue
<template>
<x-button block type="primary">撑满父容器</x-button>
<x-button narrow>窄按钮</x-button>
<x-button size="large" narrow>大型窄按钮</x-button>
<x-button loading-fill type="primary" loading>填充加载</x-button>
</template>按钮组
vue
<template>
<x-button-group type="primary">
<x-button>上一页</x-button>
<x-button>下一页</x-button>
</x-button-group>
<x-button-group status="danger" size="small">
<x-button>移除</x-button>
<x-button>清空</x-button>
<x-button disabled>禁用</x-button>
</x-button-group>
</template>按需导入
ts
import { Button, ButtonGroup } from 'x-next';样式按需引入(base.css 为共享基础层,多个组件只需引入一次):
ts
import 'x-next/style/base.css';
import 'x-next/style/button.css';Button Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
disabled | 是否禁用 | boolean | false |
block | 是否撑满父容器 | boolean | false |
loading | 是否展示加载状态;加载中会拦截点击 | boolean | false |
loadingFill | 加载中是否使用填充态,会让加载图标覆盖按钮内容区域 | boolean | false |
debounce | 点击后保持 loading 态的时间,单位 ms,用于防重复点击 | number | 0 |
shape | 按钮形状 | 'round' | 'circle' | 'square' | - |
link | 是否展示为链接按钮样式 | boolean | false |
type | 按钮类型 | 'default' | 'primary' | 'dashed' | 'outline' | 'text' | 'default' |
htmlType | 原生按钮类型;模板中使用 html-type | 'button' | 'submit' | 'reset' | 'button' |
status | 按钮状态 | 'default' | 'success' | 'warning' | 'strong' | 'danger' | 'info' | 'default' |
plain | 是否朴素样式 | boolean | false |
size | 按钮尺寸 | 'mini' | 'small' | 'medium' | 'large' | 'huge' | 'medium' |
border | 是否显示边框 | boolean | true |
narrow | 是否使用窄按钮,无内边距 | boolean | false |
Button Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
click | 点击按钮且按钮未禁用、未加载时触发 | event: MouseEvent |
Button Slots
| 插槽名 | 说明 |
|---|---|
default | 按钮内容 |
prefix | 前置内容 |
suffix | 后置内容 |
icon | 图标内容,会渲染在文字前 |
ButtonGroup
ButtonGroup 可作为按钮组样式容器使用,并可通过组级 type、status、shape、size、disabled 为内部 Button 提供默认值。子按钮显式传入同名属性时,以子按钮自身属性为准。
ButtonGroup Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
type | 子按钮默认类型 | 'default' | 'primary' | 'dashed' | 'outline' | 'text' | - |
status | 子按钮默认状态 | 'default' | 'success' | 'warning' | 'strong' | 'danger' | 'info' | - |
shape | 子按钮默认形状 | 'round' | 'circle' | 'square' | - |
size | 子按钮默认尺寸 | 'mini' | 'small' | 'medium' | 'large' | 'huge' | - |
disabled | 是否禁用所有子按钮 | boolean | false |