u
This commit is contained in:
1 parent
6277fb2f9e
commit
8ecac0d7dd
270 files changed
+40438
-529
No files matched your search
@@ -0,0 +1,95 @@
|
||||
import { useMemo, useState } from 'react'
|
||||
|
||||
export interface ValidationRule {
|
||||
required?: boolean
|
||||
pattern?: RegExp
|
||||
minLength?: number
|
||||
maxLength?: number
|
||||
validator?: (value: any) => boolean
|
||||
message?: string
|
||||
}
|
||||
|
||||
export interface FormValidationResult {
|
||||
[key: string]: {
|
||||
isValid: boolean
|
||||
errorMessage: string
|
||||
}
|
||||
}
|
||||
|
||||
export default function useFormValidation<T extends Record<string, any>>(
|
||||
values: T,
|
||||
rules: { [K in keyof T]?: ValidationRule }, // <-- 可选字段,message 可选
|
||||
) {
|
||||
const [validationResults, setValidationResults] = useState<FormValidationResult>({})
|
||||
|
||||
const validate = () => {
|
||||
const newValidationResults: FormValidationResult = {}
|
||||
|
||||
for (const field in rules) {
|
||||
const value = values[field]
|
||||
const strValue = String(value ?? '')
|
||||
const fieldRules = rules[field as keyof T]
|
||||
if (!fieldRules)
|
||||
continue
|
||||
|
||||
let isValid = true
|
||||
let errorMessage = ''
|
||||
const getDefaultMessage = (type: string) => `${field} 是${type}`
|
||||
|
||||
if (fieldRules.required && (value === undefined || value === null || strValue === '')) {
|
||||
isValid = false
|
||||
errorMessage = fieldRules.message || getDefaultMessage('必填项')
|
||||
}
|
||||
|
||||
if (isValid && fieldRules.pattern && !fieldRules.pattern.test(strValue)) {
|
||||
isValid = false
|
||||
errorMessage = fieldRules.message || '格式不正确'
|
||||
}
|
||||
|
||||
if (isValid && fieldRules.minLength && strValue.length < fieldRules.minLength) {
|
||||
isValid = false
|
||||
errorMessage = fieldRules.message || `最少输入 ${fieldRules.minLength} 个字符`
|
||||
}
|
||||
|
||||
if (isValid && fieldRules.maxLength && strValue.length > fieldRules.maxLength) {
|
||||
isValid = false
|
||||
errorMessage = fieldRules.message || `最多输入 ${fieldRules.maxLength} 个字符`
|
||||
}
|
||||
|
||||
if (isValid && fieldRules.validator && !fieldRules.validator(value)) {
|
||||
isValid = false
|
||||
errorMessage = fieldRules.message || '自定义验证未通过'
|
||||
}
|
||||
|
||||
newValidationResults[field] = { isValid, errorMessage }
|
||||
}
|
||||
|
||||
setValidationResults(newValidationResults)
|
||||
return newValidationResults
|
||||
}
|
||||
|
||||
const isValid = useMemo(() => {
|
||||
return Object.keys(rules).every((field) => {
|
||||
const value = values[field as keyof T]
|
||||
const strValue = String(value ?? '')
|
||||
const fieldRules = rules[field as keyof T]
|
||||
if (!fieldRules)
|
||||
return true
|
||||
|
||||
if (fieldRules.required && (value === undefined || value === null || strValue === ''))
|
||||
return false
|
||||
if (fieldRules.pattern && !fieldRules.pattern.test(strValue))
|
||||
return false
|
||||
if (fieldRules.minLength && strValue.length < fieldRules.minLength)
|
||||
return false
|
||||
if (fieldRules.maxLength && strValue.length > fieldRules.maxLength)
|
||||
return false
|
||||
if (fieldRules.validator && !fieldRules.validator(value))
|
||||
return false
|
||||
|
||||
return true
|
||||
})
|
||||
}, [values, rules])
|
||||
|
||||
return { validationResults, isValid, validate }
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import type { KeyboardEvent } from 'react-native'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Keyboard } from 'react-native'
|
||||
|
||||
/**
|
||||
* useKeyboardHeight - 获取键盘高度的 Hooks
|
||||
* @returns {number} 当前键盘高度,键盘收起时为 0
|
||||
*/
|
||||
export function useKeyboardHeight() {
|
||||
const [keyboardHeight, setKeyboardHeight] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
const onKeyboardShow = (e: KeyboardEvent) => {
|
||||
setKeyboardHeight(e.endCoordinates.height)
|
||||
}
|
||||
|
||||
const onKeyboardHide = () => {
|
||||
setKeyboardHeight(0)
|
||||
}
|
||||
|
||||
const showSub = Keyboard.addListener('keyboardDidShow', onKeyboardShow)
|
||||
const hideSub = Keyboard.addListener('keyboardDidHide', onKeyboardHide)
|
||||
|
||||
return () => {
|
||||
showSub.remove()
|
||||
hideSub.remove()
|
||||
}
|
||||
}, [])
|
||||
|
||||
return keyboardHeight
|
||||
}
|
||||
Reference in new issue
Block a user