视频演示地址:
📋 目录
- 概述
- 特性
- 快速开始
- API 参考
- 使用示例
- 主题配置
- 最佳实践
- 常见问题
- 总结
概述
SecondaryButton是控件库中的次要按钮组件,适用于次要操作场景。与PrimaryButton的主要区别在于:
- PrimaryButton:实心背景,用于主要操作(如"提交"、“确认”)
- SecondaryButton:边框样式,用于次要操作(如"取消"、“返回”)
设计理念
次要按钮采用边框样式设计,具有以下特点:
- 视觉层次:通过边框而非实心背景,降低视觉权重
- 操作区分:与主要按钮形成明确的视觉对比
- 品牌标识:左下角自动包含品牌标识(圆圈红字"PC")
- 主题统一:所有样式配置都在代码中,方便定制
特性
✨ 核心特性
- ✅边框样式:带边框的次要按钮,无实心背景
- ✅多种尺寸:支持 small、medium、large 三种尺寸
- ✅图标支持:支持左侧或右侧图标
- ✅加载状态:内置加载动画
- ✅禁用状态:支持禁用状态,自动调整样式
- ✅品牌标识:自动包含左下角品牌标识
- ✅主题配置:所有样式都可通过代码配置
🎨 视觉特点
- 正常状态:蓝色边框 + 蓝色文字 + 白色背景
- 悬停状态:浅蓝色背景(通过系统自动处理)
- 按下状态:更深的背景色
- 禁用状态:灰色边框 + 灰色文字 + 50% 透明度
快速开始
基础用法
import{SecondaryButton}from'../components/base'@Entry @Component struct MyPage{build(){Column({space:20}){// 基础次要按钮SecondaryButton({text:'取消'})// 带图标的次要按钮SecondaryButton({text:'返回',icon:$r('app.media.icon_back'),iconPosition:'left'})}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Center)}}关于点击事件处理
SecondaryButton的onClickBuilder属性是@BuilderParam类型,需要使用@Builder或@LocalBuilder方法初始化。在实际项目中,推荐使用以下方式处理点击事件:
- 状态管理方式:通过
@State变量和普通Button的onClick来处理 - 自定义事件系统:创建自定义事件处理机制
- @Builder 方法:如果需要使用
onClickBuilder,需要定义@Builder方法
本文档中的示例主要展示按钮的视觉效果和样式配置,点击事件处理可以通过上述方式实现。
与 PrimaryButton 配合使用
@Entry @Component struct ButtonGroupExample{// 点击事件处理handleCancel(){console.info('取消操作')}handleConfirm(){console.info('确认操作')}build(){Row({space:12}){// 次要操作SecondaryButton({text:'取消'})// 主要操作PrimaryButton({text:'确认'})}.width('100%').justifyContent(FlexAlign.End)}}注意:onClickBuilder是@BuilderParam类型,需要使用@Builder或@LocalBuilder方法初始化。如果需要处理点击事件,建议通过状态管理或自定义事件系统实现。
API 参考
Props
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
text | string | '按钮' | 按钮文字 |
icon | ResourceStr? | undefined | 按钮图标(可选) |
iconPosition | 'left' | 'right' | 'left' | 图标位置 |
buttonSize | 'small' | 'medium' | 'large' | 'medium' | 按钮尺寸 |
loading | boolean | false | 是否加载中 |
disabled | boolean | false | 是否禁用 |
showBrand | boolean | true | 是否显示品牌标识 |
buttonWidth | string | number? | undefined | 按钮宽度(可选) |
buttonHeight | string | number? | undefined | 按钮高度(可选) |
onClickBuilder | @BuilderParam () => void? | undefined | 点击事件回调(需要使用 @Builder 或 @LocalBuilder 方法) |
尺寸规格
| 尺寸 | 高度 | 字体大小 | 图标大小 | 内边距 |
|---|---|---|---|---|
small | 32vp | 12vp | 16vp | 12vp × 6vp |
medium | 40vp | 14vp | 20vp | 16vp × 8vp |
large | 48vp | 16vp | 24vp | 24vp × 12vp |
使用示例
1. 基础按钮
@Entry @Component struct ButtonExample1{build(){Column({space:15}){SecondaryButton({text:'取消'})SecondaryButton({text:'返回'})SecondaryButton({text:'上一步'})}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Center)}}2. 不同尺寸
@Entry @Component struct ButtonExample2{build(){Column({space:15}){SecondaryButton({text:'小按钮',buttonSize:'small'})SecondaryButton({text:'中等按钮',buttonSize:'medium'})SecondaryButton({text:'大按钮',buttonSize:'large'})}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Center)}}3. 图标按钮
@Entry @Component struct ButtonExample3{build(){Column({space:15}){// 左侧图标SecondaryButton({text:'下载',icon:$r('app.media.icon_download'),iconPosition:'left'})// 右侧图标SecondaryButton({text:'下一步',icon:$r('app.media.icon_arrow_right'),iconPosition:'right'})// 仅图标(通过空文字实现)SecondaryButton({text:'',icon:$r('app.media.icon_settings'),buttonWidth:40,buttonHeight:40})}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Center)}}4. 加载状态
@Entry @Component struct ButtonExample4{@State loading:boolean=false// 处理保存操作handleSave(){this.loading=true// 模拟异步操作setTimeout(()=>{this.loading=falseconsole.info('保存完成')},2000)}build(){Column({space:20}){SecondaryButton({text:'保存',loading:this.loading})// 使用普通按钮触发加载状态Button(){Text(this.loading?'保存中...':'点击保存')}.onClick(()=>{this.handleSave()}).enabled(!this.loading)Text('点击按钮查看加载状态').fontSize(12).fontColor('#999999')}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Center)}}说明:由于onClickBuilder需要使用@Builder方法,这里使用普通Button来演示点击事件处理。实际项目中,可以通过状态管理或自定义事件系统来处理按钮点击。
5. 禁用状态
@Entry @Component struct ButtonExample5{@State formValid:boolean=falsebuild(){Column({space:20}){SecondaryButton({text:'重置',disabled:!this.formValid})Text('表单验证通过后才能重置').fontSize(12).fontColor('#999999')}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Center)}}6. 按钮组合
@Entry @Component struct ButtonExample6{build(){Column({space:20}){// 左右对齐的按钮组Row({space:12}){SecondaryButton({text:'取消',buttonSize:'medium'})PrimaryButton({text:'确认',buttonSize:'medium'})}.width('100%').justifyContent(FlexAlign.End)// 居中对齐的按钮组Row({space:12}){SecondaryButton({text:'上一步',buttonSize:'medium'})SecondaryButton({text:'下一步',buttonSize:'medium'})}.width('100%').justifyContent(FlexAlign.Center)}.width('100%').height('100%').padding(20)}}7. 自定义宽度
@Entry @Component struct ButtonExample7{build(){Column({space:15}){SecondaryButton({text:'全宽按钮',buttonWidth:'100%',buttonSize:'large'})SecondaryButton({text:'中等宽度(60%)',buttonWidth:'60%',buttonSize:'medium'})SecondaryButton({text:'固定宽度(200vp)',buttonWidth:200,buttonSize:'small'})}.width('100%').height('100%').padding(20).justifyContent(FlexAlign.Center)}}8. 表单场景
@Entry @Component struct FormExample{@State formData:{name:stringemail:string}={name:'',email:''}@State submitting:boolean=false// 重置表单handleReset(){this.formData={name:'',email:''}}// 提交表单handleSubmit(){if(!this.formData.name||!this.formData.email){return}this.submitting=true// 模拟提交setTimeout(()=>{this.submitting=falseconsole.info('提交成功')},2000)}build(){Column({space:20}){// 表单内容TextInput({placeholder:'姓名'}).onChange((value:string)=>{this.formData.name=value})TextInput({placeholder:'邮箱'}).onChange((value:string)=>{this.formData.email=value})// 按钮组Row({space:12}){SecondaryButton({text:'重置',disabled:this.submitting})PrimaryButton({text:'提交',loading:this.submitting,disabled:!this.formData.name||!this.formData.email})}.width('100%').justifyContent(FlexAlign.End)// 使用普通按钮处理点击事件Row({space:12}){Button('重置表单').onClick(()=>{this.handleReset()}).enabled(!this.submitting)Button('提交表单').onClick(()=>{this.handleSubmit()}).enabled(!this.submitting&&this.formData.name&&this.formData.email)}.width('100%').justifyContent(FlexAlign.End)}.width('100%').height('100%').padding(20)}}说明:在实际项目中,可以通过状态管理或自定义事件系统来处理按钮点击事件。这里展示了如何通过普通Button来处理点击事件,同时使用SecondaryButton和PrimaryButton来展示视觉效果。
主题配置
SecondaryButton 的所有样式都通过ComponentTheme配置,所有配置都在代码中,不依赖JSON文件。
修改按钮颜色
import{ComponentTheme}from'../theme/ComponentTheme'// 修改次要按钮文字颜色ComponentTheme.SECONDARY_BUTTON_TEXT_COLOR='#007AFF'// 修改次要按钮边框颜色ComponentTheme.SECONDARY_BUTTON_BORDER_COLOR='#007AFF'// 修改次要按钮悬停背景色ComponentTheme.SECONDARY_BUTTON_BACKGROUND_HOVER='#F0F7FF'// 修改次要按钮按下背景色ComponentTheme.SECONDARY_BUTTON_BACKGROUND_ACTIVE='#E0EFFF'// 修改禁用状态颜色ComponentTheme.SECONDARY_BUTTON_TEXT_DISABLED='#CCCCCC'ComponentTheme.SECONDARY_BUTTON_BORDER_DISABLED='#E5E5E5'批量配置
import{ComponentTheme}from'../theme/ComponentTheme'// 使用 setTheme 方法批量配置ComponentTheme.setTheme({primaryColor:'#007AFF',borderRadius:8,spacing:16})自定义主题
// 在应用启动时配置import{ComponentTheme}from'./theme/ComponentTheme'// 设置自定义次要按钮颜色ComponentTheme.SECONDARY_BUTTON_TEXT_COLOR='#34C759'// 绿色ComponentTheme.SECONDARY_BUTTON_BORDER_COLOR='#34C759'ComponentTheme.SECONDARY_BUTTON_BACKGROUND_HOVER='#F0F9F4'最佳实践
1. 按钮组合使用
推荐:主要操作使用 PrimaryButton,次要操作使用 SecondaryButton
Row({space:12}){SecondaryButton({text:'取消'})PrimaryButton({text:'确认'})}2. 尺寸选择
- small:用于紧凑空间,如表格操作列
- medium:默认尺寸,适用于大多数场景
- large:用于重要操作或大屏幕显示
3. 图标使用
- 使用图标增强按钮的可识别性
- 常用操作使用标准图标(如返回、下载、设置)
- 图标位置根据阅读习惯选择(中文:左侧,英文:根据上下文)
4. 加载状态
- 异步操作时显示加载状态
- 加载期间自动禁用按钮
- 操作完成后恢复按钮状态
5. 禁用状态
- 根据表单验证状态动态禁用
- 提供明确的禁用原因提示
- 避免频繁切换禁用状态
6. 响应式设计
- 使用百分比宽度适配不同屏幕
- 在小屏幕上考虑使用全宽按钮
- 保持按钮之间的合理间距
常见问题
Q1: SecondaryButton 和 PrimaryButton 有什么区别?
A: 主要区别在于视觉样式:
- PrimaryButton:实心背景,用于主要操作
- SecondaryButton:边框样式,用于次要操作
功能上两者基本相同,都支持图标、加载、禁用等状态。
Q2: 如何隐藏品牌标识?
A: 设置showBrand: false:
SecondaryButton({text:'按钮',showBrand:false})注意:不推荐隐藏品牌标识,这会影响控件库的识别性。
Q3: 如何自定义按钮颜色?
A: 直接修改ComponentTheme中的静态属性:
ComponentTheme.SECONDARY_BUTTON_TEXT_COLOR='#34C759'ComponentTheme.SECONDARY_BUTTON_BORDER_COLOR='#34C759'Q4: 如何处理按钮点击事件?
A:onClickBuilder是@BuilderParam类型,需要使用@Builder或@LocalBuilder方法。推荐使用状态管理或自定义事件系统:
@Entry @Component struct MyPage{@State count:number=0// 方式1:使用状态管理handleClick(){this.count++console.info('按钮被点击')}// 方式2:使用 @Builder 方法(如果需要使用 onClickBuilder)@BuilderonClickHandler(){this.count++console.info('按钮被点击')}build(){Column({space:20}){// 使用普通按钮处理点击Button('点击我').onClick(()=>{this.handleClick()})// 使用 SecondaryButton 展示样式SecondaryButton({text:'次要按钮'})Text(`点击次数:${this.count}`)}.width('100%').height('100%').padding(20)}}Q5: 如何实现按钮的悬停效果?
A: HarmonyOS 系统会自动处理按钮的悬停效果,无需手动实现。如果需要自定义,可以通过修改ComponentTheme中的悬停颜色配置。
Q6: 按钮文字可以换行吗?
A: 按钮文字默认不换行。如果需要多行文字,建议使用其他组件(如 TextButton)或自定义实现。
总结
SecondaryButton 是控件库中的次要按钮组件,具有以下核心特性:
- 视觉层次:通过边框样式降低视觉权重
- 功能完整:支持图标、加载、禁用等多种状态
- 尺寸灵活:三种尺寸满足不同场景需求
- 易于使用:简单的 API,开箱即用
- 主题配置:所有样式都可通过代码配置
- 品牌标识:自动包含品牌标识,保持视觉统一
关键要点
- ✅ 使用
buttonSize属性选择合适尺寸 - ✅ 使用
loading属性处理异步操作 - ✅ 使用
disabled属性控制按钮状态 - ✅ 通过
ComponentTheme自定义样式 - ✅ 与
PrimaryButton配合使用,形成清晰的视觉层次
适用场景
- 表单中的"取消"、"重置"按钮
- 对话框中的次要操作按钮
- 列表中的次要操作按钮
- 需要降低视觉权重的操作按钮
下一篇预告:TextButton(文本按钮)详解
本文档属于《鸿蒙PC UI控件库开发系列文章》第3篇