前言
在鸿蒙应用开发中,按钮是最基础、使用频率最高的交互组件 ,分为两类核心控件:普通点击按钮 Button、开关选择按钮 Toggle。二者都依托 @State 状态装饰器实现页面自动刷新,本文结合课堂实战代码,从零讲解按钮用法、样式美化、状态联动逻辑,看完就能直接上手开发登录页、设置开关、计数器等场景。
一、核心前置知识:@State 状态驱动
所有按钮交互的底层逻辑都是状态驱动 UI:
- 使用
@State修饰变量,标记为响应式数据; - 点击按钮修改变量值,框架自动触发
build()重新渲染页面; - 普通
private变量修改后页面无变化,仅@State变量具备刷新能力。
基础示例:数字计数器按钮
scss
@Entry
@Component
struct CountDemo{
@State count:number = 0
build(){
Column({space:20}){
Text(`当前数值:${this.count}`).fontSize(50)
Button("递加+")
.width("45%")
.height(50)
.fontSize(22)
.onClick(()=>{
// 限制数值范围0~10
if(this.count < 10) this.count++
})
}
.width("100%").height("100%").padding(20)
}
}

二、普通按钮 Button:点击交互专用
1. 基础语法
scss
Button("按钮文字")
.width(尺寸)
.height(尺寸)
.borderRadius(圆角)
.fontSize(文字大小)
.onClick(()=>{
// 点击触发逻辑
})
2. 常用样式属性
width/height:宽高支持数字(vp)、百分比字符串'90%'borderRadius:圆角,数值越大按钮越圆润fontSize:按钮内文字字号backgroundColor:自定义按钮背景色fontColor:按钮文字颜色
3. 实战场景:登录弹窗按钮
登录页面的「登录 / 注册」双按钮,点击判断输入框内容弹出提示框:
javascript
Row({space:20}){
Button('登录')
.width('45%')
.height(50)
.fontSize(20)
.onClick(()=>{
if (this.username && this.password) {
AlertDialog.show({title:"登录成功",message:`欢迎你,${this.username}`})
}else {
AlertDialog.show({title:"登录失败",message:`用户名或密码不能为空`})
}
})
Button('注册')
.width('45%')
.height(50)
.fontSize(20)
}
三、开关按钮 Toggle:选择类交互专用
Toggle 多用于设置项、勾选场景,提供三种样式,通过 type 区分:
ToggleType.Switch:滑动开关(最常用,消息推送、文字变色案例)ToggleType.Checkbox:复选框(多选勾选)ToggleType.None:纯按钮样式
1. 基础结构
scss
Toggle({
type: ToggleType.Switch, // 开关类型
isOn: this.状态变量 // 绑定开关选中状态
})
.width(宽)
.height(高)
.selectedColor(Color.Red) // 打开时开关底色
.enabled(false) // 禁用开关,不可点击
.onChange((value:boolean)=>{
// 切换时触发,value为最新开关状态
})
2. 实战 1:开关切换文字颜色
滑动开关,文字红绿切换,对应上文 Toggle5 案例:
less
@Entry
@Component
struct ToggleColorDemo{
@State isOpen:boolean = false
build() {
Column(){
Text("这是一个会变色的文字")
.fontSize(26)
// 三元表达式绑定状态切换颜色
.fontColor(this.isOpen?Color.Red:Color.Green)
Toggle({
type:ToggleType.Switch,
isOn:this.isOpen
})
.width(60)
.height(30)
.onChange((value:boolean)=>{
this.isOpen = !this.isOpen
})
}
.width('100%').height('100%')
}
}

3. 实战 2:禁用只读开关
设置 .enabled(false) 后,开关灰色不可点击,适用于只读设置项:
scss
Text("禁用状态开关(不可点击)").fontSize(20)
Toggle({
type:ToggleType.Switch,
isOn:true
})
.width(50)
.height(28)
.enabled(false) // 禁用
四、Button 和 Toggle 核心区别
表格
| 组件 | 适用场景 | 核心事件 | 状态特点 |
|---|---|---|---|
| Button | 提交、跳转、弹窗、计数 | onClick(单次点击) | 无自带选中状态,需手动定义变量 |
| Toggle | 设置项、勾选、功能开关 | onChange(状态切换) | 自带布尔选中状态 isOn |
五、综合实战:完整登录页面按钮组合
整合 TextInput、Toggle、Button,实现「记住密码 + 登录判断」完整交互:
scss
@Entry
@Component
struct LoginPage{
@State isRemb:boolean=true;
@State username:string="";
@State password:string="";
build() {
Column({space:30}){
Text("账号登录").fontSize(30).fontWeight(FontWeight.Bolder)
// 账号输入框
TextInput({text:this.username,placeholder:"请输入账号"})
.width('100%').height(50).borderRadius(12)
.onChange(v=>this.username=v)
// 密码输入框
TextInput({text:this.password,placeholder:"请输入密码"})
.width('100%').height(50).borderRadius(12).type(InputType.Password)
.onChange(v=>this.password=v)
// Toggle记住密码
Row({space:20}){
Text("记住密码").fontSize(20)
Toggle({type:ToggleType.Switch,isOn:this.isRemb})
.width(50).height(28)
.onChange(v=>this.isRemb=v)
}
// 登录、注册按钮
Row({space:20}){
Button("登录")
.width("45%").height(50)
.onClick(()=>{
if(this.username&&this.password){
AlertDialog.show({title:"登录成功",message:`欢迎${this.username}`})
}else{
AlertDialog.show({title:"登录失败",message:"账号密码不能为空"})
}
})
Button("注册").width("45%").height(50)
}
}
.width("100%").height("100%").padding(20).justifyContent(FlexAlign.Center)
}
}

六、开发踩坑总结
- 状态不刷新 :变量忘记加
@State修饰,修改后页面无变化; - Toggle 状态不同步 :
isOn没有绑定响应式变量,切换后 UI 不变; - 按钮尺寸溢出 :宽度直接写数字会适配异常,布局铺满推荐使用
'100%'; - 禁用开关失效 :
.enabled(false)写在Toggle大括号内部,必须写在外部链式调用。
结尾
按钮是鸿蒙交互的基石,Button 负责点击动作,Toggle 负责状态选择,搭配 @State 响应式状态就能实现绝大多数页面交互。后续可以拓展进阶用法:图片按钮、自定义渐变按钮、多按钮联动切换等功能。