--- name: cpn-basic-number-input description: 帮助 AI 正确使用 UDesign NumberInput 组件(数字输入框组件)。当需要使用 NumberInput 时加载此技能。 --- # 使用 NumberInput 组件 ## 技能概述 这是 NumberInput 数字输入框组件 ## 使用指南 ### 引入方式 ```jsx import { NumberInput } from '@ucloud-fe/react-components'; ``` > ⚠️ **全局规范 - 所有组件通用**: > - 生成纯 JavaScript (JSX) 代码,**不要使用 TypeScript 类型注解** > - **禁止**使用 `@alicloud/*`、`@aliyun/*`、`antd` 等外部组件库 > - 优先使用 UDesign 组件,不要用 HTML 原生标签替代 ### 基本用法 ```jsx class Demo extends React.Component { render() { return (
((v / 2) | 0) * 2} />
); } } ``` ### API 参数 | 属性 | 类型 | 默认值 | 必填 | 说明 | |------|------|--------|------|------| | value | `unknown` | - | - | 值,受控 | | defaultValue | `unknown` | - | - | 默认值,非受控 | | focusOnUpDown | `unknown` | `true` | - | | | autoFocus | `unknown` | - | - | | | onChange | `unknown` | `function noop() {}` | - | 修改回调 | | onNumberChange | `unknown` | `function noop() {}` | - | 有效的修改回调,使用按钮改变值或者输入、回车后失焦时触发,可防止监听到无效的回调 | | onKeyDown | `unknown` | `function noop() {}` | - | | | onKeyUp | `unknown` | - | - | | | onEnter | `unknown` | `function noop() {}` | - | | | disabled | `unknown` | - | - | 禁用 | | onFocus | `unknown` | `function noop() {}` | - | | | onBlur | `unknown` | `function noop() {}` | - | | | readOnly | `unknown` | - | - | 只读 | | max | `unknown` | - | - | 最大值 | | min | `unknown` | `-MAX_SAFE_INTEGER` | - | 最小值 | | step | `unknown` | `1` | - | 按钮每次变动大小 | | upStep | `unknown` | - | - | 增加按钮点击增加的大小,会覆盖 step | | downStep | `unknown` | - | - | 减少按钮点击减少的大小,会覆盖 step | | upHandler | `unknown` | - | - | 自定义'+'按钮 | | downHandler | `unknown` | - | - | 自定义'-'按钮 | | formatter | `unknown` | - | - | 定义数值展示格式化 | | parser | `unknown` | `function defaultParser(input) { return input.replace(/[^\w.-]+/g, ''); }` | - | 定义输入内容过滤 | | precision | `unknown` | - | - | 精度,小数点位数 | | className | `unknown` | - | - | | | style | `unknown` | - | - | | | styleType | `unknown` | `StyleType[0]` | - | 样式风格 | | size | `unknown` | `'md'` | - | 尺寸 | | suffix | `unknown` | - | - | 自定义后缀 | | inputStyle | `unknown` | - | - | input框自定义样式 | | computeValidNumber | `unknown` | `v => v` | - | 计算合法值 | | hideHandler | `unknown` | - | - | 是否隐藏操作按钮 | | tooltip | `unknown` | - | - | 输入提示,hover 和输入焦点时显示,可直接传入 tooltip 内容,或传入 tooltip 的 props,props 参考 tooltip 组件文档 注意,如果使用自定义 props 中的 visible 和 onVisibleChange 则需要自己去控制 tooltip 的显示隐藏 | ### 全部 Demo
演示 ```jsx const { Size, StyleType } = NumberInput; class Demo extends React.Component { constructor(props) { super(props); this.state = { disabled: false, styleType: StyleType[0], readOnly: false, hideHandler: false, size: 'md', suffix: null }; } render() { const { disabled, styleType, readOnly, size, hideHandler } = this.state; const itemLayout = { labelCol: { span: 2 }, controllerCol: { span: 10 } }; return (
this.setState({ size })} options={Size.map(size => ({ value: size }))} /> this.setState({ styleType })} options={StyleType.map(styleType => ({ value: styleType }))} /> this.setState({ disabled })}> disabled this.setState({ readOnly })}> readOnly this.setState({ max: value })} placeholder="max" /> this.setState({ min: value })} placeholder="min" /> this.setState({ step: value })} placeholder="step" /> this.setState({ hideHandler })} /> this.setState({ suffix: e.target.value })} placeholder="suffix" />
); } } ```
disabled - 禁用 ```jsx class Demo extends React.Component { render() { return (
); } } ```
readOnly - 只读 ```jsx class Demo extends React.Component { render() { return (
); } } ```
max/min - 最大值/最小值 ```jsx class Demo extends React.Component { render() { return (
); } } ```
formatter - 自定义展示格式 ```jsx class Demo extends React.Component { render() { return (
`${v} 台`} defaultValue={3} />
`买了 ${v} 个苹果`} defaultValue={2} inputStyle={{ width: 100 }} />
); } } ```
parser - 自定义可接受输入格式 ```jsx class Demo extends React.Component { render() { return (
v.replace(/[^\d]+/g, '')} />
v.replace(/[^\d/.]+/g, '')} />
); } } ```
precision - 小数点个数 ```jsx class Demo extends React.Component { render() { return (
); } } ```
step - 步长 ```jsx class Demo extends React.Component { render() { return (
); } } ```
styleType - 样式类型 ```jsx const { StyleType } = NumberInput; class Demo extends React.Component { render() { return (
{StyleType.map(styleType => (
))}
); } } ```
size - 尺寸 ```jsx const { Size, StyleType } = NumberInput; class Demo extends React.Component { render() { return (
{Size.map(size => (
{StyleType.map(styleType => (
))}
))}
); } } ```
suffix - 后缀 ```jsx const { StyleType } = NumberInput; class Demo extends React.Component { render() { const max = 10; return (
{StyleType.map(styleType => (
))}
); } } ```
inputStyle - 自定义输入框样式 ```jsx const { StyleType } = NumberInput; class Demo extends React.Component { render() { return (
{StyleType.map(styleType => (
))}
); } } ```
upHandler/downHandler - 自定义 +/- 按钮 ```jsx class Demo extends React.Component { render() { return (
} downHandler={} />
); } } ```
computeValidNumber - 自定义合法值的方法 ```jsx class Demo extends React.Component { render() { return (
((v / 2) | 0) * 2} />
); } } ```
onNumberChange - 只监听有效数值修改 ```jsx class Demo extends React.Component { render() { return (
console.log('onChange:', ...args)} onNumberChange={(...args) => console.log('onNumberChange:', ...args)} />
); } } ```
uncontrolled - 受控非受控 ```jsx const layout = { style: { margin: 8 } }; class Demo extends React.Component { constructor(props) { super(props); this.state = { value: 4 }; } render() { const { value } = this.state; return (
this.setState({ value })} {...layout} />
); } } ```
tooltip - 提示文案 ```jsx const { StyleType } = NumberInput; class Demo extends React.Component { render() { return (
{StyleType.map(styleType => (
))}
); } } ```
## 最佳实践 1. **设置合理的 min/max**:限制输入范围防止非法值 2. **使用 onNumberChange 而非 onChange**:`onNumberChange` 只在有效值变化时触发,避免中间态 3. **formatter 和 parser 配对使用**:格式化显示时需要同时提供 parser 解析输入 4. **使用 suffix 添加单位**:比 formatter 更简单的方式添加单位后缀 ### 常见场景 #### 资源数量选择 ```jsx ``` #### 带单位的数值输入 ```jsx ``` ## 常见问题 ### Q: onChange 和 onNumberChange 的区别? A: `onChange` 在每次输入时都会触发(包括输入中间态),`onNumberChange` 只在有效数字确定时触发(按钮点击、回车、失焦)。 ### Q: 如何自定义合法值的计算方式? A: 使用 `computeValidNumber` 属性,传入一个函数接收当前数值和选项,返回合法的数值。 ## 注意事项 _(待补充)_