6.0 KiB
6.0 KiB
name, overview, todos
| name | overview | todos | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| button-enhance | 为 Button 组件补齐行为层能力:nativeType、disabled、loading、size、block 五个 prop,配套样式与 token,并更新 App.vue 展示页示例。 |
|
产品概述
为现有 Button 组件补齐行为层能力,使其从"纯视觉变体"升级为可直接用于表单和异步场景的交互组件,同时保持当前克制、token 驱动的设计语言。
核心功能
- 原生 type 控制:新增
nativeTypeprop,默认button,避免放入表单时误触发表单提交 - 禁用态:新增
disabledprop,禁用点击、hover/active 效果,光标提示not-allowed - 加载态:新增
loadingprop,显示内联 SVG spinner,标记aria-busy,加载期间禁止交互且布局宽度不跳动 - 尺寸三档:新增
sizeprop(small / default / large),通过 token 驱动高度、内边距与字号 - 通栏模式:新增
blockprop,按钮占满整行宽度,适配表单底部操作区
技术栈
- Vue 3
<script setup>组合式 API - Sass/SCSS(项目已装
sass ^1.102.0,沿用<style scoped lang="scss">+@use './index.scss'模式) - 设计 token 驱动(CSS 变量,命名沿用
--fms-前缀)
实现方案
总体策略
不改动现有 6 种视觉变体(default/secondary/outline/ghost/danger/link)和基础交互,只在组件上追加行为层 prop 与对应 class,向后完全兼容。尺寸三档、禁用态、加载态全部通过 token 与 scoped 样式实现,单一来源,符合项目既有模式。
关键决策
nativeType默认button:HTML 原生<button>默认type="submit",显式设默认值消除表单误提交隐患,同时保留透传覆盖能力。- loading 复用 disabled 语义:
loading时计算属性isDisabled = disabled || loading,统一走原生:disabled路径,避免重复点击;同时挂aria-busy供屏幕阅读器识别。 - spinner 用内联 SVG:项目无图标库,参考
ThemeToggle.vue/ColorThemePicker.vue的内联<svg>写法,不引入新依赖;spinner 前置、文字保留占位,避免加载时按钮宽度跳变。 - 尺寸走 token 而非写死数值:新增
--fms-control-height-sm/lg、--fms-control-padding-x-sm/lg、--fms-font-size-sm/lg三组 token,与现有--fms-control-height(default)形成三档体系,延续「font-size 已 token 化」的既有约定。 - disabled 态覆盖 hover/active:
:disabled下取消transform: scale(0.97)与背景/文字颜色变化,保证「看起来不能点」;spinner 旋转动画纳入prefers-reduced-motion: reduce降级,与现有动效处理一致。
实现要点
button.vue 改造
- 新增 props:
nativeType(String,默认'button')、disabled(Boolean,默认false)、loading(Boolean,默认false)、size(String,默认'default',可选'small' | 'large')、block(Boolean,默认false)。 classes计算属性在原有button、button-${type}基础上追加:size !== 'default'时加button-${size},block加button-block,loading加button-loading。- 模板绑定
:type="nativeType"、:disabled="isDisabled"、:aria-busy="loading || undefined",loading时在<slot>前渲染 spinner SVG。 - 沿用
<style scoped lang="scss">@use './index.scss';</style>不改变隔离方式。
index.scss 扩展
- 新增
.button-small/.button-large:分别引用 sm/lg 的 height、padding-x、font-size token。 - 新增
.button-block:display: flex; width: 100%。 - 新增
.button:disabled:cursor: not-allowed、opacity降低、取消 hover/active 的颜色与缩放效果(需覆盖各 type 的 hover 规则)。 - 新增
.button-spinner:固定尺寸(约 14px)、animation: spin旋转,@media (prefers-reduced-motion: reduce)下animation: none。
tokens.css 扩展
- 在「控件」分组补充:
--fms-control-height-sm: 24px、--fms-control-height-lg: 40px、--fms-control-padding-x-sm: 8px、--fms-control-padding-x-lg: 14px。 - 在「字体」分组补充:
--fms-font-size-sm: 12px、--fms-font-size-lg: 16px。 - 深色模式
.dark下尺寸 token 与浅色一致,无需重复覆盖。
App.vue 展示页更新
- 在现有 6 种 type 行下方补充示例分组:禁用态(
disabled)、加载态(loading)、三种尺寸(small/default/large)、通栏(block)。 - 保持现有
.button-row布局与卡片容器风格一致。
目录结构
fms-vue/src/
├── theme/
│ └── tokens.css # [MODIFY] 新增 sm/lg 尺寸与字号 token
├── components/ui/button/
│ ├── button.vue # [MODIFY] 新增 5 个 prop、spinner 模板、aria/disabled 绑定
│ └── index.scss # [MODIFY] 新增 size/block/disabled/loading/spinner 样式
└── App.vue # [MODIFY] 补充禁用、加载、尺寸、通栏示例
验证方式
pnpm dev启动后检查:disabled 按钮不可点击且光标为 not-allowed;loading 按钮显示 spinner 且重复点击无效、宽度不跳动;三种尺寸视觉正确;block 按钮占满容器宽度。- 表单场景验证:
<Button nativeType="submit">可正常提交,默认按钮不触发提交。