带单位的 InputNumber
    image.png
    注意点:InputNumber手动删除值后,值为 null;不是 0,需要兼容下

    1. import React, { useState, useEffect } from 'react';
    2. import { string, func } from 'prop-types';
    3. import { InputNumber, Select } from 'antd';
    4. import { words, isFunction, isNil } from 'lodash-es';
    5. export const options = [
    6. {label: '秒', value: 's'},
    7. {label: '分钟', value: 'm'},
    8. {label: '小时', value: 'h'},
    9. {label: '天', value: 'd'},
    10. {label: '月', value: 'm'},
    11. ]
    12. const initState = { value: 1, unit: 'm' }
    13. function formatUnit({ value, unit }) {
    14. return `${value}${unit}`;
    15. }
    16. InputNumberWithUnit.propTypes = {
    17. value: string,
    18. onChange: func,
    19. };
    20. function InputNumberWithUnit({ value, onChange }) {
    21. const [state, setState] = useState(initState);
    22. useEffect(() => {
    23. const [val, unit = initState.unit] = words(value);
    24. if (isNil(val)) return;
    25. setState({ unit, value: val });
    26. }, [value]);
    27. function handleChange(key, val) {
    28. setState(prevState => {
    29. const _state = { ...prevState, [key]: val };
    30. if (isFunction(onChange)) {
    31. onChange(formatUnit(_state));
    32. }
    33. return _state;
    34. });
    35. }
    36. return (
    37. <InputNumber
    38. value={state.value}
    39. onChange={val => handleChange('value', val)}
    40. min={0}
    41. addonAfter={(
    42. <Select
    43. value={state.unit}
    44. // 手动清空,值为 null
    45. onChange={val => handleChange('unit', val: val ?? 0)}
    46. options={options}
    47. // 80px https://tailwindcss.com/docs/width
    48. className='w-20'
    49. />
    50. )}
    51. />
    52. );
    53. }
    54. export default InputNumberWithUnit;