首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >鸿蒙PC UI控件库 - PrimaryButton 主要按钮详解

鸿蒙PC UI控件库 - PrimaryButton 主要按钮详解

作者头像
红目香薰
发布2025-12-16 16:57:16
发布2025-12-16 16:57:16
680
举报
文章被收录于专栏:CSDNToQQCodeCSDNToQQCode

视频演示地址:

https://www.bilibili.com/video/BV1jomdBBE4H/

在这里插入图片描述
在这里插入图片描述

系列文章第2篇 | 作者:红目香薰 | 更新时间:2025年

📖 前言

在上一篇文章中,我们介绍了控件库的品牌标识系统,这是所有控件的基础设施。从本文开始,我们将逐一介绍控件库中的实际控件。

本文要介绍的是 PrimaryButton(主要按钮),这是控件库中的第1个基础控件,也是最常用的按钮组件。PrimaryButton 支持图标、加载状态、多种尺寸,并且自动包含品牌标识。


🎯 什么是 PrimaryButton?

PrimaryButton 是一个功能完整的主要按钮组件,具有以下特点:

  1. 多种尺寸:支持 small、medium、large 三种尺寸
  2. 图标支持:可以在按钮左侧或右侧添加图标
  3. 加载状态:支持显示加载动画,常用于异步操作
  4. 状态管理:支持正常、禁用、加载等多种状态
  5. 品牌标识:自动在左下角显示品牌标识
  6. 主题配置:所有样式都可通过 ComponentTheme 配置
适用场景
  • ✅ 主要操作按钮(如"提交"、“确认”、“保存”)
  • ✅ 需要图标提示的操作按钮
  • ✅ 需要显示加载状态的异步操作按钮
  • ✅ 需要统一视觉风格的主要按钮

🚀 快速开始

引入组件
代码语言:javascript
复制
import { PrimaryButton } from '../components/base'
基础使用

最简单的使用方式:

代码语言:javascript
复制
@Entry
@Component
struct MyPage {
  build() {
    Column({ space: 20 }) {
      // 基础按钮
      PrimaryButton({
        text: '点击我'
      })
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

📚 完整功能详解

1. 基础按钮

最简单的按钮,只需要设置文字:

代码语言:javascript
复制
PrimaryButton({
  text: '提交'
})
2. 带图标的按钮

可以在按钮左侧或右侧添加图标:

代码语言:javascript
复制
// 左侧图标
PrimaryButton({
  text: '保存',
  icon: $r('app.media.icon_save'),
  iconPosition: 'left'
})

// 右侧图标
PrimaryButton({
  text: '下一步',
  icon: $r('app.media.icon_arrow_right'),
  iconPosition: 'right'
})
3. 不同尺寸

支持三种尺寸:small、medium、large

代码语言:javascript
复制
Column({ space: 20 }) {
  // 小按钮
  PrimaryButton({
    text: '小按钮',
    buttonSize: 'small'
  })
  
  // 中等按钮(默认)
  PrimaryButton({
    text: '中等按钮',
    buttonSize: 'medium'
  })
  
  // 大按钮
  PrimaryButton({
    text: '大按钮',
    buttonSize: 'large'
  })
}

尺寸对比

尺寸

高度

字体大小

图标大小

内边距

small

32vp

12vp

16vp

12vp

medium

40vp

14vp

20vp

16vp

large

48vp

16vp

24vp

24vp

4. 加载状态

在异步操作时显示加载动画:

代码语言:javascript
复制
@Entry
@Component
struct MyPage {
  @State loading: boolean = false

  build() {
    Column({ space: 20 }) {
      PrimaryButton({
        text: '提交数据',
        loading: this.loading,
        onClickCallback: () => {
          this.loading = true
          // 模拟异步操作
          setTimeout(() => {
            this.loading = false
          }, 2000)
        }
      })
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

加载状态特点

  • 自动显示加载动画(LoadingProgress)
  • 自动禁用按钮点击
  • 加载时隐藏图标,显示加载动画
5. 禁用状态

禁用按钮,常用于表单验证或权限控制:

代码语言:javascript
复制
@Entry
@Component
struct MyPage {
  @State formValid: boolean = false

  build() {
    Column({ space: 20 }) {
      PrimaryButton({
        text: '提交',
        disabled: !this.formValid
      })
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

禁用状态特点

  • 按钮变为灰色(使用 PRIMARY_COLOR_DISABLED
  • 透明度降低到 0.5
  • 无法点击
6. 点击事件处理

使用 onClickCallback 处理点击事件:

代码语言:javascript
复制
@Entry
@Component
struct MyPage {
  handleClick() {
    console.info('按钮被点击了')
    // 执行你的业务逻辑
  }

  build() {
    Column({ space: 20 }) {
      PrimaryButton({
        text: '点击我',
        onClickCallback: () => {
          this.handleClick()
        }
      })
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}
7. 自定义宽度和高度

可以自定义按钮的宽度和高度:

代码语言:javascript
复制
// 固定宽度
PrimaryButton({
  text: '固定宽度按钮',
  buttonWidth: 200
})

// 百分比宽度
PrimaryButton({
  text: '全宽按钮',
  buttonWidth: '100%'
})

// 自定义高度
PrimaryButton({
  text: '自定义高度',
  buttonHeight: 50
})
8. 隐藏品牌标识

如果需要隐藏品牌标识(不推荐):

代码语言:javascript
复制
PrimaryButton({
  text: '无标识按钮',
  showBrand: false
})

⚙️ 主题配置

PrimaryButton 的所有样式都通过 ComponentTheme 配置,所有配置都在代码中,不依赖JSON文件。

修改按钮颜色
代码语言:javascript
复制
import { ComponentTheme } from '../theme/ComponentTheme'

// 修改主色调
ComponentTheme.PRIMARY_COLOR = '#007AFF'        // 正常状态
ComponentTheme.PRIMARY_COLOR_HOVER = '#0051D5'   // 悬停状态
ComponentTheme.PRIMARY_COLOR_ACTIVE = '#0040A8'  // 按下状态
ComponentTheme.PRIMARY_COLOR_DISABLED = '#CCCCCC' // 禁用状态
修改圆角
代码语言:javascript
复制
ComponentTheme.BORDER_RADIUS = 8  // 默认圆角
批量配置
代码语言:javascript
复制
ComponentTheme.setTheme({
  primaryColor: '#007AFF',
  borderRadius: 8
})

📖 API 参考

PrimaryButton 属性

属性名

类型

默认值

说明

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

按钮高度(可选)

onClickCallback

() => void?

undefined

点击事件回调

尺寸样式对照表

尺寸

高度

字体

图标

内边距(左右)

内边距(上下)

small

32vp

12vp

16vp

12vp

6vp

medium

40vp

14vp

20vp

16vp

8vp

large

48vp

16vp

24vp

24vp

12vp


💡 最佳实践

1. 合理使用尺寸

根据使用场景选择合适的尺寸:

代码语言:javascript
复制
// ✅ 推荐:主要操作使用 medium 或 large
PrimaryButton({ text: '提交', buttonSize: 'medium' })

// ✅ 推荐:次要操作或空间受限时使用 small
PrimaryButton({ text: '取消', buttonSize: 'small' })

// ✅ 推荐:重要操作使用 large
PrimaryButton({ text: '立即购买', buttonSize: 'large' })
2. 加载状态的使用

在异步操作时及时显示加载状态:

代码语言:javascript
复制
@State loading: boolean = false

async handleSubmit() {
  this.loading = true
  try {
    await submitData()
    // 成功处理
  } catch (error) {
    // 错误处理
  } finally {
    this.loading = false
  }
}

PrimaryButton({
  text: '提交',
  loading: this.loading,
  onClickCallback: () => this.handleSubmit()
})
3. 图标的使用

使用图标增强按钮的可识别性:

代码语言:javascript
复制
// ✅ 推荐:使用语义明确的图标
PrimaryButton({
  text: '保存',
  icon: $r('app.media.icon_save'),
  iconPosition: 'left'
})

// ✅ 推荐:操作类按钮使用右侧图标
PrimaryButton({
  text: '下一步',
  icon: $r('app.media.icon_arrow_right'),
  iconPosition: 'right'
})
4. 禁用状态的使用

在表单验证或权限控制时使用禁用状态:

代码语言:javascript
复制
@State formValid: boolean = false
@State hasPermission: boolean = true

PrimaryButton({
  text: '提交',
  disabled: !this.formValid || !this.hasPermission
})
5. 保持品牌标识

除非特殊需求,建议保持品牌标识显示:

代码语言:javascript
复制
// ✅ 推荐:保持品牌标识
PrimaryButton({ text: '提交' })

// ⚠️ 仅在特殊场景下隐藏
PrimaryButton({ text: '提交', showBrand: false })

🔍 常见问题

Q1: 如何自定义按钮颜色?

通过 ComponentTheme 修改:

代码语言:javascript
复制
ComponentTheme.PRIMARY_COLOR = '#FF6B35'  // 自定义主色
Q2: 加载状态时如何阻止重复点击?

加载状态会自动禁用按钮,无需额外处理:

代码语言:javascript
复制
PrimaryButton({
  text: '提交',
  loading: this.loading,  // loading 为 true 时自动禁用
  onClickCallback: () => {
    this.loading = true
    // 执行异步操作
  }
})
Q3: 如何实现按钮的悬停效果?

按钮会自动使用 ComponentTheme.PRIMARY_COLOR_HOVER 作为悬停颜色,你只需要配置:

代码语言:javascript
复制
ComponentTheme.PRIMARY_COLOR_HOVER = '#0051D5'
Q4: 图标资源如何准备?

图标资源需要放在 resources/base/media/ 目录下,然后在代码中引用:

代码语言:javascript
复制
// 使用资源引用
icon: $r('app.media.icon_save')

// 或使用路径
icon: 'common/icons/save.png'
Q5: 按钮文字可以动态更新吗?

可以,使用 @State 管理文字:

代码语言:javascript
复制
@State buttonText: string = '提交'

PrimaryButton({
  text: this.buttonText
})

// 动态更新
this.buttonText = '提交中...'

📝 完整示例代码

示例1:基础按钮组
代码语言:javascript
复制
import { PrimaryButton } from '../components/base'

@Entry
@Component
struct ButtonExample1 {
  build() {
    Column({ space: 20 }) {
      // 基础按钮
      PrimaryButton({
        text: '提交'
      })
      
      // 带图标按钮
      PrimaryButton({
        text: '保存',
        icon: $r('app.media.icon_save'),
        iconPosition: 'left'
      })
      
      // 不同尺寸
      Row({ space: 20 }) {
        PrimaryButton({ text: '小', buttonSize: 'small' })
        PrimaryButton({ text: '中', buttonSize: 'medium' })
        PrimaryButton({ text: '大', buttonSize: 'large' })
      }
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}
示例2:加载状态
代码语言:javascript
复制
import { PrimaryButton } from '../components/base'

@Entry
@Component
struct ButtonExample2 {
  @State loading: boolean = false

  async handleSubmit() {
    this.loading = true
    // 模拟异步操作
    await new Promise(resolve => setTimeout(resolve, 2000))
    this.loading = false
    console.info('提交成功')
  }

  build() {
    Column({ space: 20 }) {
      PrimaryButton({
        text: '提交数据',
        loading: this.loading,
        onClickCallback: () => {
          this.handleSubmit()
        }
      })
      
      Text(this.loading ? '提交中...' : '点击提交')
        .fontSize(14)
        .fontColor('#666666')
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}
示例3:表单提交
代码语言:javascript
复制
import { PrimaryButton } from '../components/base'

@Entry
@Component
struct ButtonExample3 {
  @State username: string = ''
  @State password: string = ''
  @State loading: boolean = false

  get formValid(): boolean {
    return this.username.length > 0 && this.password.length > 0
  }

  async handleLogin() {
    if (!this.formValid) return
    
    this.loading = true
    try {
      // 执行登录逻辑
      await login(this.username, this.password)
      console.info('登录成功')
    } catch (error) {
      console.error('登录失败', error)
    } finally {
      this.loading = false
    }
  }

  build() {
    Column({ space: 20 }) {
      TextInput({ placeholder: '用户名' })
        .onChange((value: string) => {
          this.username = value
        })
      
      TextInput({ placeholder: '密码', type: InputType.Password })
        .onChange((value: string) => {
          this.password = value
        })
      
      PrimaryButton({
        text: '登录',
        loading: this.loading,
        disabled: !this.formValid,
        buttonWidth: '100%',
        onClickCallback: () => {
          this.handleLogin()
        }
      })
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}
示例4:图标按钮组合
代码语言:javascript
复制
import { PrimaryButton } from '../components/base'

@Entry
@Component
struct ButtonExample4 {
  build() {
    Column({ space: 20 }) {
      // 左侧图标
      PrimaryButton({
        text: '保存',
        icon: $r('app.media.icon_save'),
        iconPosition: 'left',
        buttonWidth: 150
      })
      
      // 右侧图标
      PrimaryButton({
        text: '下一步',
        icon: $r('app.media.icon_arrow_right'),
        iconPosition: 'right',
        buttonWidth: 150
      })
      
      // 仅图标(通过空文字实现)
      PrimaryButton({
        text: '',
        icon: $r('app.media.icon_add'),
        buttonWidth: 48,
        buttonHeight: 48
      })
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}
示例5:全宽按钮
代码语言:javascript
复制
import { PrimaryButton } from '../components/base'

@Entry
@Component
struct ButtonExample5 {
  build() {
    Column({ space: 15 }) {
        PrimaryButton({
          text: '全宽按钮',
          buttonWidth: '100%',
          buttonSize: 'large'
        })
        
        PrimaryButton({
          text: '中等宽度',
          buttonWidth: '60%',
          buttonSize: 'medium'
        })
        
        PrimaryButton({
          text: '小宽度',
          buttonWidth: 120,
          buttonSize: 'small'
        })
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

🎯 总结

PrimaryButton 是控件库中的第一个基础控件,具有以下核心特性:

  1. 功能完整:支持图标、加载、禁用等多种状态
  2. 尺寸灵活:三种尺寸满足不同场景需求
  3. 易于使用:简单的 API,开箱即用
  4. 主题配置:所有样式都可通过代码配置
  5. 品牌标识:自动包含品牌标识,保持视觉统一
关键要点
  • ✅ 使用 buttonSize 属性选择合适尺寸
  • ✅ 使用 loading 属性处理异步操作
  • ✅ 使用 disabled 属性控制按钮状态
  • ✅ 使用 iconiconPosition 添加图标
  • ✅ 通过 ComponentTheme 自定义样式

下一篇预告:《鸿蒙PC UI控件库 - SecondaryButton 次要按钮详解》


本文是鸿蒙PC UI控件库系列文章的第2篇,后续将陆续发布更多控件的详细教程。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 视频演示地址:
  • 📖 前言
  • 🎯 什么是 PrimaryButton?
    • 适用场景
  • 🚀 快速开始
    • 引入组件
    • 基础使用
  • 📚 完整功能详解
    • 1. 基础按钮
    • 2. 带图标的按钮
    • 3. 不同尺寸
    • 4. 加载状态
    • 5. 禁用状态
    • 6. 点击事件处理
    • 7. 自定义宽度和高度
    • 8. 隐藏品牌标识
  • ⚙️ 主题配置
    • 修改按钮颜色
    • 修改圆角
    • 批量配置
  • 📖 API 参考
    • PrimaryButton 属性
    • 尺寸样式对照表
  • 💡 最佳实践
    • 1. 合理使用尺寸
    • 2. 加载状态的使用
    • 3. 图标的使用
    • 4. 禁用状态的使用
    • 5. 保持品牌标识
  • 🔍 常见问题
    • Q1: 如何自定义按钮颜色?
    • Q2: 加载状态时如何阻止重复点击?
    • Q3: 如何实现按钮的悬停效果?
    • Q4: 图标资源如何准备?
    • Q5: 按钮文字可以动态更新吗?
  • 📝 完整示例代码
    • 示例1:基础按钮组
    • 示例2:加载状态
    • 示例3:表单提交
    • 示例4:图标按钮组合
    • 示例5:全宽按钮
  • 🎯 总结
    • 关键要点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档