useForm
useForm()
是一個自訂的 Vue Composition API,讓您輕鬆管理表單的值和狀態。
用法
以下程式碼展示了一個基本的使用範例:
<script setup lang="ts">
import { useForm } from '@vorms/core'
const { errors, dirty, register, handleSubmit, handleReset } = useForm({
initialValues: {
drink: '',
sugar: 30,
},
validate (values) {
const errors: Record<string, any> = {}
if (!values.drink) {
errors.drink = 'This is required!!'
}
return errors
},
onSubmit(data, { setSubmitting }) {
// 如果 `onSubmit()` 方法是同步的
// 您需要自己調用 `setSubmitting(false)`。
setSubmitting(false)
}
})
// 基本用法
// 需要在 <input> 上綁定 `attrs`,
// 以支援 `validateMode` 和 `reValidateMode`。
const { value: drink, attrs: drinkFieldAttrs } = register('drink')
// 新增欄位級別的驗證。
const { value: sugar, attrs: sugarFieldAttrs } = register('sugar', {
validate(value) {
return value > 100 ? 'This max number is 100' : undefined
}
})
</script>
<template>
<form @submit="handleSubmit" @reset="handleReset">
<div>
<input v-model="drink" type="text" v-bind="drinkFieldAttrs">
<div>{{ errors.drink }}</div>
</div>
<div>
<input v-model.number="sugar" type="number" v-bind="sugarFieldAttrs">
<div>{{ errors.sugar }}</div>
</div>
<button type="reset">Reset</button>
<button type="submit">Submit</button>
</form>
</template>
<script setup lang="ts">
import { useForm } from '@vorms/core'
const { errors, dirty, register, handleSubmit, handleReset } = useForm({
initialValues: {
drink: '',
sugar: 30,
},
validate (values) {
const errors: Record<string, any> = {}
if (!values.drink) {
errors.drink = 'This is required!!'
}
return errors
},
onSubmit(data, { setSubmitting }) {
// 如果 `onSubmit()` 方法是同步的
// 您需要自己調用 `setSubmitting(false)`。
setSubmitting(false)
}
})
// 基本用法
// 需要在 <input> 上綁定 `attrs`,
// 以支援 `validateMode` 和 `reValidateMode`。
const { value: drink, attrs: drinkFieldAttrs } = register('drink')
// 新增欄位級別的驗證。
const { value: sugar, attrs: sugarFieldAttrs } = register('sugar', {
validate(value) {
return value > 100 ? 'This max number is 100' : undefined
}
})
</script>
<template>
<form @submit="handleSubmit" @reset="handleReset">
<div>
<input v-model="drink" type="text" v-bind="drinkFieldAttrs">
<div>{{ errors.drink }}</div>
</div>
<div>
<input v-model.number="sugar" type="number" v-bind="sugarFieldAttrs">
<div>{{ errors.sugar }}</div>
</div>
<button type="reset">Reset</button>
<button type="submit">Submit</button>
</form>
</template>
參數
initialValues (必填)
這是表單的初始值,將用 dirty comparison(骯髒比較)為基礎。
Type
tstype Values = Record<string, any>
type Values = Record<string, any>
initialErrors
這是表單的初始錯誤訊息。
- Type
FormErrors<Values>
- Default:
undefined
initialTouched
這是表單的初始觸摸(touched)狀態。
- Type
FormTouched<Values>
- Default:
undefined
validateMode
這個選項允許您在首次提交之前,配置驗證模式。
- Type
'blur' | 'input' | 'change' | 'submit'
- Default
'submit'
reValidateMode
這個選項允許您在首次提交之後配置驗證模式。
默認情況下,驗證是在輸入事件變更(input change event)時觸發的。
INFO
即使您的 reValidationMode
沒有設置為 submit
,Vorms 仍然會在提交之前重新驗證。
- Type
'blur' | 'input' | 'change' | 'submit'
- Default
'change'
validateOnMounted
這個選項允許您配置當元件被掛載(mounted)時,是否應該進行驗證。
- Type
boolean
- Default
false
validate
validate
是一個表單級別的驗證方法。此屬性接受表單的 values
作為參數。
您可以返回 error
物件(errors object)或 undefined 來確定這些值是否有效。
Type
tsfunction validate(values: Values): void | object | Promise<FormErrors<Values>>
function validate(values: Values): void | object | Promise<FormErrors<Values>>
validate 可以是以下其中一種:
同步方法,返回
errors
物件。tsimport { useForm } from '@vorms/core' const { values } = useForm({ initialValues: { name: '', age: 10 }, validate(values) { const errors = {} if(!values.name) { errors.name = 'name is required.' } if(typeof values.age !== 'number') { errors.age = 'age should be a number.' } return errors }, onSubmit(values) { console.log(values) } })
import { useForm } from '@vorms/core' const { values } = useForm({ initialValues: { name: '', age: 10 }, validate(values) { const errors = {} if(!values.name) { errors.name = 'name is required.' } if(typeof values.age !== 'number') { errors.age = 'age should be a number.' } return errors }, onSubmit(values) { console.log(values) } })
非同步方法,返回一個 Promise,該 Promise 解析為包含
errors
的物件。tsimport { useForm } from '@vorms/core' const { values } = useForm({ initialValues: { name: '', age: 10 }, validate() { return new Promise((resolve) => { setTimeout(() => { const errors = {} if(!values.name) { errors.name = 'name is required.' } if(typeof values.age !== 'number') { errors.age = 'age should be a number.' } resolve(errors) }, 300) }) }, onSubmit(values) { console.log(values) } })
import { useForm } from '@vorms/core' const { values } = useForm({ initialValues: { name: '', age: 10 }, validate() { return new Promise((resolve) => { setTimeout(() => { const errors = {} if(!values.name) { errors.name = 'name is required.' } if(typeof values.age !== 'number') { errors.age = 'age should be a number.' } resolve(errors) }, 300) }) }, onSubmit(values) { console.log(values) } })
您可以使用
@vorms/resolvers
來整合其他外部驗證庫,如 Yup 或 Zod。bashnpm install @vorms/resolvers
npm install @vorms/resolvers
tsimport { useForm } from '@vorms/core' import { yupResolver } from '@vorms/resolvers/yup'; import * as yup from 'yup'; const schema = yup.object().shape({ name: yup.string().required('Name is required!!'), age: yup.number().required('Age is required!!') }) const { values } = useForm({ initialValues: { name: '', age: 10 }, validate: yupResolver(schema), onSubmit(values) { console.log(values) } })
import { useForm } from '@vorms/core' import { yupResolver } from '@vorms/resolvers/yup'; import * as yup from 'yup'; const schema = yup.object().shape({ name: yup.string().required('Name is required!!'), age: yup.number().required('Age is required!!') }) const { values } = useForm({ initialValues: { name: '', age: 10 }, validate: yupResolver(schema), onSubmit(values) { console.log(values) } })
onSubmit (必填)
這是您的表單提交處理程序,它將傳遞您表單的值(values
)。但如果驗證失敗,則不會調用此處理程序。
Type
tsfunction onSubmit (values: Values, helper: FormSubmitHelper): void | Promise<any>
function onSubmit (values: Values, helper: FormSubmitHelper): void | Promise<any>
tsinterface FormSubmitHelper { setSubmitting: (isSubmitting: boolean) => void; initialValues: Values; }
interface FormSubmitHelper { setSubmitting: (isSubmitting: boolean) => void; initialValues: Values; }
參數
values
: 需驗證的值(values
)。helper
: 一些在提交表單時可能有幫助的狀態或方法。Name Description setSubmitting
強制設定 isSubmitting initialValues
表單的初始值
Important
當 onSubmit()
方法是非同步的時候,isSubmitting
變數會在完成之後自動設置為 false
。
相反地,如果 onSubmit()
是同步的,你必須手動呼叫 setSubmitting(false)
來重置 isSubmitting
。
onInvalid
這是您的無效處理程序,當使用無效值提交表單時會被呼叫。
回傳
values
目前表單的值。
- Type
Values
Note
如果您直接使用 v-model 來綁定表單的值(values
),驗證將只在提交之前被調用。
errors
這是一個包含所有當前驗證錯誤的物件。其形狀會與表單值的形狀匹配。
- Type
ComputedRef<FormErrors<Values>>
touched
這是一個包含所有曾經被觸摸(touched)過的欄位對象。其形狀將與表單的值的形狀相匹配
- Type
ComputedRef<FormTouched<Values>>
dirty
如果現在的值沒有 initialValues
與深度相等(deeply equal),回傳 true
。
- Type
ComputedRef<boolean>
setValues
這個方法允許你手動更新表單的值。
- Type
(values: Values, shouldValidate?: boolean)
setFieldValue
這個方法允許你手動設置欄位的值
- Type
(name: string, value: unknown, shouldValidate?: boolean)
setErrors
這個方法允許您手動設置表單的錯誤訊息。
- Type
(errors: FormErrors<Values>)
setFieldError
這個方法允許您手動設置欄位的錯誤訊息。
- Type
(name: string, error: string | string[] | Record<string, any> | undefined)
submitCount
用戶嘗試提交表單的次數。
- Type
ComputedRef<number>
isSubmitting
當表單正在提交時(submitting),這個方法將回傳 true
。
如果 onSubmit()
是一個同步方法,那麼您需要手動呼叫 setSubmitting(false)
來將狀態設置為 false
。
- Type
Ref<boolean>
isValidating
當正在進行驗證時,這個方法將回傳 true
。
- Type
ComputedRef<boolean>
resetForm
重置整個表單的狀態。您可以選擇性地傳遞參數來設置表單的狀態為您想要的值。
Type
tsfunction resetForm(nextState?: Partial<FormResetState<Values>>): void interface FormResetState<Values> { // 表單的值。 values: Values; // 一個包含已觸摸(touched)過的欄位名稱的物件 touched: FormTouched<Values>; // 一個包含有錯誤的欄位名稱的物件。 errors: FormErrors<Values>; // 用戶嘗試提交的次數 submitCount: number; }
function resetForm(nextState?: Partial<FormResetState<Values>>): void interface FormResetState<Values> { // 表單的值。 values: Values; // 一個包含已觸摸(touched)過的欄位名稱的物件 touched: FormTouched<Values>; // 一個包含有錯誤的欄位名稱的物件。 errors: FormErrors<Values>; // 用戶嘗試提交的次數 submitCount: number; }
register
此方法可讓您取得特定欄位值(value)、狀態(state)和屬性(attribute),您也可以為該欄位新增驗證。
Type
tsfunction register<Value>(name: MaybeRefOrGetter<string>, options?: FieldRegisterOptions<Value>): UseFormRegisterReturn<Value>
function register<Value>(name: MaybeRefOrGetter<string>, options?: FieldRegisterOptions<Value>): UseFormRegisterReturn<Value>
Show Type Detail
tsinterface FieldRegisterOptions<Value> { validate?: FieldValidator<Value>; } type FieldValidator<Value> = (value: Value) => string | void | Promise<string | void> type UseFormRegisterReturn<Value> = { value: WritableComputedRef<Value>; dirty: ComputedRef<boolean>; error: ComputedRef<string | undefined>; touched: ComputedRef<boolean | undefined>; attrs: ComputedRef<FieldAttrs>; } interface FieldAttrs { name: string; onBlur(event: Event): void; onChange(): void; onInput(): void }
interface FieldRegisterOptions<Value> { validate?: FieldValidator<Value>; } type FieldValidator<Value> = (value: Value) => string | void | Promise<string | void> type UseFormRegisterReturn<Value> = { value: WritableComputedRef<Value>; dirty: ComputedRef<boolean>; error: ComputedRef<string | undefined>; touched: ComputedRef<boolean | undefined>; attrs: ComputedRef<FieldAttrs>; } interface FieldAttrs { name: string; onBlur(event: Event): void; onChange(): void; onInput(): void }
Example
vue<script setup lang="ts"> const { register } = useForm({ initialValues: { drink: 'Bubble Tea' } }) const { value, attrs } = register('drink', { // Field level validation validate(value) { return !value ? 'What do you want to drink ?' : undefined } }) </script> <template> <input v-model="value" type="text" v-bind="attrs" /> </template>
<script setup lang="ts"> const { register } = useForm({ initialValues: { drink: 'Bubble Tea' } }) const { value, attrs } = register('drink', { // Field level validation validate(value) { return !value ? 'What do you want to drink ?' : undefined } }) </script> <template> <input v-model="value" type="text" v-bind="attrs" /> </template>
handleSubmit
提交處理程序。如果事件(event
)被傳遞,它將在內部呼叫 event.preventDefault()
。
Type
tsfunction handleSubmit(event?: Event): void
function handleSubmit(event?: Event): void
handleReset
重置處理程序。如果事件(event
)被傳遞,它將在內部呼叫 event.preventDefault()
。
Type
tsfunction handleReset(event?: Event): void
function handleReset(event?: Event): void
validateForm
表單的驗證器。 它將運行 表單級別(form level) 驗證。
Type
tsfunction validateForm(values?: Values): Promise<FormErrors<Values>>
function validateForm(values?: Values): Promise<FormErrors<Values>>
validateField
特定欄位的驗證器,如果該欄位的驗證已註冊。
Type
tsfunction validateField(name: string): Promise<void>
function validateField(name: string): Promise<void>