视频演示地址:

https://www.bilibili.com/video/BV1jomdBBE4H/
在这里插入图片描述

📋 目录


概述

NumberInput 是控件库中专用于数字输入的组件,支持步进器、范围限制、精度控制等功能,适用于数量输入、价格输入、百分比输入等需要精确数字控制的场景。

设计理念

数字输入框采用精确易用设计,具有以下特点:

  1. 步进控制:支持通过按钮快速增减数值
  2. 范围限制:支持设置最小值和最大值
  3. 精度控制:支持设置小数位数
  4. 智能验证:自动验证和修正输入值
  5. 品牌标识:左下角自动包含品牌标识(圆圈红字"PC")
  6. 主题统一:所有样式配置都在代码中,方便定制

适用场景

  • 数量输入:商品数量、库存数量等
  • 价格输入:商品价格、金额等
  • 百分比输入:折扣、比例等
  • 参数设置:各种数值参数配置

特性

✨ 核心特性

  • 步进器按钮:支持通过 +/- 按钮快速增减数值
  • 范围限制:支持设置最小值和最大值
  • 步进值:支持自定义步进值(如每次增减5)
  • 精度控制:支持设置小数位数(0-10位)
  • 智能验证:自动验证和修正输入值
  • 标签和提示:支持标签、提示文本、错误提示
  • 多种尺寸:支持 small、medium、large 三种尺寸
  • 状态管理:支持禁用、只读、必填等状态
  • 品牌标识:自动包含左下角品牌标识
  • 主题配置:所有样式都可通过代码配置

🎨 视觉特点

  • 正常状态:白色背景 + 灰色边框 + 步进器按钮
  • 错误状态:红色边框 + 红色错误提示
  • 禁用状态:灰色背景 + 灰色文字 + 灰色边框 + 禁用按钮
  • 只读状态:正常样式但不可编辑

快速开始

基础用法

import { NumberInput } from '../components/base'

@Entry
@Component
struct MyPage {
  @State number: number = 0

  build() {
    Column({ space: 20 }) {
      // 基础数字输入框
      NumberInput({
        value: $number,
        placeholder: '请输入数字'
      })
      
      // 带标签的数字输入框
      NumberInput({
        value: $number,
        placeholder: '请输入数量',
        label: '数量'
      })
      
      // 带范围限制的数字输入框
      NumberInput({
        value: $number,
        placeholder: '请输入0-100之间的数字',
        label: '百分比',
        min: 0,
        max: 100
      })
    }
    .width('100%')
    .height('100%')
    .padding(20)
    .justifyContent(FlexAlign.Center)
  }
}

关于双向绑定

NumberInput 使用 @Link 实现双向绑定,需要使用 $variableName 语法:

@State number: number = 0

NumberInput({
  value: $number  // 使用 $ 创建双向绑定
})

API 参考

Props

属性名 类型 默认值 说明
value @Link number - 数字值(必需,双向绑定)
placeholder string '请输入数字' 占位符文本
label string '' 标签文本
hint string '' 提示文本(显示在输入框下方)
errorMessage string '' 错误提示文本(优先级高于 hint)
inputSize 'small' | 'medium' | 'large' 'medium' 输入框尺寸
disabled boolean false 是否禁用
readonly boolean false 是否只读
required boolean false 是否必填
min number Number.NEGATIVE_INFINITY 最小值
max number Number.POSITIVE_INFINITY 最大值
step number 1 步进值
precision number 0 精度(小数位数,0-10)
showStepper boolean true 是否显示步进器按钮
showBrand boolean true 是否显示品牌标识
inputWidth string | number '100%' 输入框宽度

尺寸规格

尺寸 高度 字体大小 按钮大小 内边距(左右)
small 48vp 14vp 24vp 12vp
medium 60vp 16vp 28vp 14vp
large 72vp 18vp 32vp 16vp

使用示例

1. 基础数字输入框

@Entry
@Component
struct NumberExample1 {
  @State number: number = 0

  build() {
    Column({ space: 15 }) {
      NumberInput({
        value: $number,
        placeholder: '请输入数字'
      })
      
      Text(`当前值:${this.number}`)
        .fontSize(14)
        .fontColor('#666')
    }
    .width('100%')
    .padding(20)
  }
}

2. 带标签和提示

@Entry
@Component
struct NumberExample2 {
  @State number: number = 0

  build() {
    Column({ space: 15 }) {
      NumberInput({
        value: $number,
        placeholder: '请输入数量',
        label: '数量',
        hint: '请输入1-100之间的数字'
      })
      
      NumberInput({
        value: $number,
        placeholder: '请输入价格',
        label: '价格',
        errorMessage: '价格不能为负数'
      })
    }
    .width('100%')
    .padding(20)
  }
}

3. 范围限制

@Entry
@Component
struct NumberExample3 {
  @State percentage: number = 50

  build() {
    Column({ space: 15 }) {
      NumberInput({
        value: $percentage,
        placeholder: '请输入0-100之间的数字',
        label: '百分比',
        min: 0,
        max: 100,
        hint: '范围:0-100'
      })
      
      Text(`当前值:${this.percentage}%`)
        .fontSize(14)
        .fontColor('#666')
    }
    .width('100%')
    .padding(20)
  }
}

4. 步进值

@Entry
@Component
struct NumberExample4 {
  @State quantity: number = 0

  build() {
    Column({ space: 15 }) {
      NumberInput({
        value: $quantity,
        placeholder: '步进值为5',
        label: '数量',
        step: 5,
        min: 0,
        max: 100,
        hint: '每次增减5'
      })
      
      Text(`当前值:${this.quantity}(步进:5)`)
        .fontSize(14)
        .fontColor('#666')
    }
    .width('100%')
    .padding(20)
  }
}

5. 精度控制

@Entry
@Component
struct NumberExample5 {
  @State price: number = 0

  build() {
    Column({ space: 15 }) {
      NumberInput({
        value: $price,
        placeholder: '保留2位小数',
        label: '价格',
        precision: 2,
        min: 0,
        step: 0.1,
        hint: '保留2位小数'
      })
      
      Text(`当前价格:¥${this.price.toFixed(2)}`)
        .fontSize(14)
        .fontColor('#666')
    }
    .width('100%')
    .padding(20)
  }
}

6. 不同尺寸

@Entry
@Component
struct NumberExample6 {
  @State number1: number = 0
  @State number2: number = 0
  @State number3: number = 0

  build() {
    Column({ space: 15 }) {
      NumberInput({
        value: $number1,
        placeholder: '小尺寸',
        inputSize: 'small'
      })
      
      NumberInput({
        value: $number2,
        placeholder: '中等尺寸(默认)',
        inputSize: 'medium'
      })
      
      NumberInput({
        value: $number3,
        placeholder: '大尺寸',
        inputSize: 'large'
      })
    }
    .width('100%')
    .padding(20)
  }
}

7. 必填和状态

@Entry
@Component
struct NumberExample7 {
  @State number1: number = 0
  @State number2: number = 100
  @State number3: number = 200

  build() {
    Column({ space: 15 }) {
      NumberInput({
        value: $number1,
        placeholder: '请输入数字',
        label: '必填项',
        required: true
      })
      
      NumberInput({
        value: $number2,
        placeholder: '请输入数字',
        label: '禁用状态',
        disabled: true
      })
      
      NumberInput({
        value: $number3,
        placeholder: '请输入数字',
        label: '只读状态',
        readonly: true
      })
    }
    .width('100%')
    .padding(20)
  }
}

8. 隐藏步进器

@Entry
@Component
struct NumberExample8 {
  @State number: number = 0

  build() {
    Column({ space: 15 }) {
      NumberInput({
        value: $number,
        placeholder: '不显示步进器按钮',
        label: '数字',
        showStepper: false
      })
      
      Text('提示:隐藏步进器后,只能通过键盘输入')
        .fontSize(14)
        .fontColor('#666')
    }
    .width('100%')
    .padding(20)
  }
}

9. 商品数量选择器

@Entry
@Component
struct ProductQuantity {
  @State quantity: number = 1
  @State price: number = 99.99

  build() {
    Column({ space: 20 }) {
      Text('商品信息')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
      
      NumberInput({
        value: $quantity,
        placeholder: '请输入数量',
        label: '数量',
        min: 1,
        max: 999,
        step: 1,
        hint: '范围:1-999'
      })
      
      NumberInput({
        value: $price,
        placeholder: '请输入价格',
        label: '单价',
        precision: 2,
        min: 0,
        step: 0.01,
        hint: '保留2位小数'
      })
      
      Text(`总价:¥${(this.quantity * this.price).toFixed(2)}`)
        .fontSize(18)
        .fontWeight(FontWeight.Bold)
        .fontColor('#007AFF')
    }
    .width('100%')
    .padding(30)
  }
}

10. 参数配置表单

@Entry
@Component
struct ConfigForm {
  @State width: number = 100
  @State height: number = 100
  @State opacity: number = 100
  @State rotation: number = 0

  build() {
    Column({ space: 20 }) {
      Text('参数配置')
        .fontSize(24)
        .fontWeight(FontWeight.Bold)
      
      NumberInput({
        value: $width,
        placeholder: '请输入宽度',
        label: '宽度',
        min: 0,
        max: 1000,
        step: 1,
        required: true
      })
      
      NumberInput({
        value: $height,
        placeholder: '请输入高度',
        label: '高度',
        min: 0,
        max: 1000,
        step: 1,
        required: true
      })
      
      NumberInput({
        value: $opacity,
        placeholder: '请输入透明度',
        label: '透明度',
        min: 0,
        max: 100,
        step: 1,
        hint: '范围:0-100'
      })
      
      NumberInput({
        value: $rotation,
        placeholder: '请输入旋转角度',
        label: '旋转角度',
        min: 0,
        max: 360,
        step: 1,
        precision: 0,
        hint: '范围:0-360度'
      })
    }
    .width('100%')
    .padding(30)
  }
}

主题配置

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

修改默认颜色

import { ComponentTheme } from '../theme/ComponentTheme'

// 修改主色(影响聚焦状态的边框颜色)
ComponentTheme.PRIMARY_COLOR = '#007AFF'

// 修改错误色(影响错误状态的边框和提示颜色)
ComponentTheme.ERROR_COLOR = '#FF3B30'

// 修改边框颜色
ComponentTheme.BORDER_COLOR = '#E5E5E5'

// 修改圆角
ComponentTheme.BORDER_RADIUS = 8

批量配置

import { ComponentTheme } from '../theme/ComponentTheme'

// 使用 setTheme 方法批量配置
ComponentTheme.setTheme({
  primaryColor: '#007AFF',
  errorColor: '#FF3B30',
  borderRadius: 8,
  spacing: 16
})

最佳实践

1. 尺寸选择

推荐:根据使用场景选择尺寸

  • small:用于紧凑空间、表格内输入
  • medium:默认尺寸,适用于大多数场景
  • large:用于重要输入或大屏幕显示

2. 范围限制

  • 设置合理范围:根据业务需求设置 minmax
  • 提供提示信息:使用 hint 说明范围要求
  • 自动修正:超出范围的值会自动修正到边界值

3. 步进值设置

  • 整数步进step: 1 适用于数量、计数等
  • 小数步进step: 0.1step: 0.01 适用于价格、百分比等
  • 自定义步进:根据业务需求设置合适的步进值

4. 精度控制

  • 整数precision: 0 适用于数量、计数等
  • 价格precision: 2 适用于金额、价格等
  • 百分比precision: 1precision: 2 适用于比例、折扣等

5. 步进器按钮

  • 默认开启showStepper: true,方便快速调整数值
  • 特殊场景:可以关闭步进器,只允许键盘输入
  • 禁用状态:禁用时步进器按钮也会自动禁用

6. 验证和提示

  • 实时验证:输入值会自动验证和修正
  • 清晰提示:使用 hint 提供输入要求说明
  • 错误提示:使用 errorMessage 显示明确的错误信息

常见问题

Q1: 如何设置无限制范围?

A: 不设置 minmax,或使用默认值:

NumberInput({
  value: $number,
  // 不设置 min 和 max,默认无限制
})

Q2: 如何禁用步进器按钮?

A: 设置 showStepper: false

NumberInput({
  value: $number,
  showStepper: false
})

Q3: 如何设置小数精度?

A: 使用 precision 属性:

NumberInput({
  value: $price,
  precision: 2  // 保留2位小数
})

Q4: 步进值如何设置?

A: 使用 step 属性:

NumberInput({
  value: $number,
  step: 5  // 每次增减5
})

Q5: 如何设置输入框宽度?

A: 使用 inputWidth 属性:

NumberInput({
  value: $number,
  inputWidth: 300  // 固定宽度
})

NumberInput({
  value: $number,
  inputWidth: '100%'  // 百分比宽度
})

Q6: 输入无效值会怎样?

A: 输入无效值(如非数字字符)时:

  • 输入过程中允许输入(如负号、小数点)
  • 失去焦点时自动修正为有效值
  • 如果输入完全无效,会恢复为当前值

Q7: 如何实现自定义验证?

A: 可以在外部监听 value 变化,进行自定义验证:

@State number: number = 0
@State errorMessage: string = ''

NumberInput({
  value: $number,
  errorMessage: this.errorMessage
})

// 在 aboutToUpdate 或其他地方验证
aboutToUpdate() {
  if (this.number < 0) {
    this.errorMessage = '不能为负数'
  } else {
    this.errorMessage = ''
  }
}

总结

NumberInput 是控件库中专用于数字输入的组件,具有以下核心特性:

  1. 步进控制:支持通过按钮快速增减数值
  2. 范围限制:支持设置最小值和最大值
  3. 精度控制:支持设置小数位数
  4. 智能验证:自动验证和修正输入值
  5. 易于使用:简单的 API,开箱即用
  6. 主题配置:所有样式都可通过代码配置
  7. 品牌标识:自动包含品牌标识,保持视觉统一

关键要点

  • ✅ 使用 $variableName 创建双向绑定
  • ✅ 使用 minmax 设置范围限制
  • ✅ 使用 step 设置步进值
  • ✅ 使用 precision 设置小数精度
  • ✅ 使用 showStepper 控制步进器显示
  • ✅ 使用 label 属性添加标签
  • ✅ 使用 hinterrorMessage 显示提示
  • ✅ 使用 inputSize 属性选择合适尺寸
  • ✅ 通过 ComponentTheme 自定义全局样式

适用场景

  • 数量输入
  • 价格输入
  • 百分比输入
  • 参数设置

下一篇预告:SearchInput(搜索输入框)详解


本文档属于《鸿蒙PC UI控件库开发系列文章》第9篇

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐