基于 AntD 封装的与原生事件一致的 Input 组件
# 封装背景
antd 的 Input 只有 onChange 这一个数据变化的事件,而且是只要数据变化就触发;而原生 input 的 onchange 事件是在 input 失去焦点的时候才会触发,oninput 事件在用户输入时触发,它是在元素值发生变化时立即触发
所以 antd Input 的 onChange 其实是原生的 oninput 事件,没有 onchange 事件,而我们有时候是需要这种场景的
故需要封装一个与原生事件一致的的 Input 组件
# 定义 Props
import { InputProps } from 'antd/lib/input'
type Value = string | number
export interface RealInputProps extends Omit<InputProps, 'onChange' | 'onInput' | 'value'> {
value: Value // 默认值
onChange?: (value: string) => void // input 失去焦点的时候才会触发
onInput?: (value: string) => void // 元素值发生变化时立即触发
}
interface State {
value: Value
oldValue: Value
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
Omit:
Construct a type with the properties of T except for those in type K.
type Omit<T, K extends string | number | symbol> = { [P in Exclude<keyof T, K>]: T[P]; }
# 在 state 中定义 value 与 oldValue,值都是 props.value
const { value, onChange, onInput, ...rest } = props
const valueTrim = `${value}`.trim()
const [state, updateState] = useImmer<State>({
value: valueTrim,
oldValue: valueTrim
})
1
2
3
4
5
6
7
2
3
4
5
6
7
# 监听 value,更新 state.value
useEffect(() => {
updateState(draft => {
draft.value = `${value}`.trim()
})
}, [value])
1
2
3
4
5
2
3
4
5
# 监听 onChange 事件,回调里更新 state.value,并调用 onInput 回调
const handleChange = e => {
const value = e.target.value
updateState(draft => {
draft.value = value
})
typeof onInput === 'function' && onInput(value)
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 监听 onBlur 事件,回调里判断 value 与 oldValue 是否相同,并做相应处理
const handleBlur = () => {
let { oldValue, value } = state
value = `${value}`.trim()
updateState(draft => {
draft.value = value
})
if (oldValue != value) {
updateState(draft => {
draft.oldValue = value
})
typeof onChange === 'function' && onChange(value)
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# 处理 ref 传递
export default forwardRef(RealInput)
1
编辑 (opens new window)
上次更新: 8/5/2022, 7:01:19 AM
- 01
- 搭配 Jenkins 实现自动化打包微前端多个项目09-15
- 02
- 自动化打包微前端多个项目09-15
- 03
- el-upload 直传阿里 oss 并且显示自带进度条和视频回显封面图06-05