您可能会发现需要将两个字段链接在一起;当一个字段的值发生变化时,另一个字段需要重新验证。 一个典型的用例是当您同时拥有 password 和 confirm_password 字段时, 您希望当 password 的值不匹配时,confirm_password 字段显示错误; 无论是哪个字段触发了值的变化。
想象以下用户流程:
在这个例子中,表单仍然会有错误存在, 因为"确认密码"字段的验证没有重新运行以标记为已接受。
为了解决这个问题,我们需要确保当密码字段更新时,"确认密码"验证会重新运行。 为此,您可以向 confirm_password 字段添加 onChangeListenTo 属性。
<script setup lang="ts">
import { useForm } from '@tanstack/vue-form'
const form = useForm({
defaultValues: {
password: '',
confirm_password: '',
},
// ...
})
</script>
<template>
<div>
<form @submit.prevent.stop="form.handleSubmit">
<div>
<form.Field name="password">
<template v-slot="{ field }">
<div>密码:</div>
<input
:value="field.state.value"
@input="
(e) => field.handleChange((e.target as HTMLInputElement).value)
"
/>
</template>
</form.Field>
<form.Field
name="confirm_password"
:validators="{
onChangeListenTo: ['password'],
onChange: ({ value, fieldApi }) => {
if (value !== fieldApi.form.getFieldValue('password')) {
return '密码不匹配'
}
return undefined
},
}"
>
<template v-slot="{ field }">
<div>确认密码:</div>
<input
:value="field.state.value"
@input="
(e) => field.handleChange((e.target as HTMLInputElement).value)
"
/>
<div v-for="(err, index) in field.state.meta.errors" :key="index">
{{ err }}
</div>
</template>
</form.Field>
</div>
<button type="submit">提交</button>
</form>
</div>
</template>
<script setup lang="ts">
import { useForm } from '@tanstack/vue-form'
const form = useForm({
defaultValues: {
password: '',
confirm_password: '',
},
// ...
})
</script>
<template>
<div>
<form @submit.prevent.stop="form.handleSubmit">
<div>
<form.Field name="password">
<template v-slot="{ field }">
<div>密码:</div>
<input
:value="field.state.value"
@input="
(e) => field.handleChange((e.target as HTMLInputElement).value)
"
/>
</template>
</form.Field>
<form.Field
name="confirm_password"
:validators="{
onChangeListenTo: ['password'],
onChange: ({ value, fieldApi }) => {
if (value !== fieldApi.form.getFieldValue('password')) {
return '密码不匹配'
}
return undefined
},
}"
>
<template v-slot="{ field }">
<div>确认密码:</div>
<input
:value="field.state.value"
@input="
(e) => field.handleChange((e.target as HTMLInputElement).value)
"
/>
<div v-for="(err, index) in field.state.meta.errors" :key="index">
{{ err }}
</div>
</template>
</form.Field>
</div>
<button type="submit">提交</button>
</form>
</div>
</template>
这同样适用于 onBlurListenTo 属性,它会在字段失去焦点时重新运行验证。