v-verify 指令
介绍
v-verify
指令用于表单校验,传入对象(rules),支持整个表单校验
使用方法
vue
<template>
<form v-verify:submit="rules" @submit="handleSubmit" @validate="handleValidate">
</template>
submit 情况下,校验整个表单
查看代码
vue
<template>
<form
:model="formDate"
v-verify:submit="{ ...rules, delay: delay }"
@submit="handleSubmit"
@validate="handleValidate"
class="custom-form"
>
<!-- 用户名 -->
<div class="form-item">
<label for="username">用户名</label>
<input type="text" id="username" name="username" v-model="formDate.username" placeholder="请输入用户名" />
<div class="error-message"></div>
</div>
<!-- 密码 -->
<div class="form-item">
<label for="password">密码</label>
<input type="password" id="password" name="password" v-model="formDate.password" placeholder="请输入密码" />
<div class="error-message"></div>
</div>
<!-- 确认密码 -->
<div class="form-item">
<label for="confirmPassword">确认密码</label>
<input
type="password"
id="confirmPassword"
name="confirmPassword"
v-model="formDate.confirmPassword"
placeholder="请再次输入密码"
/>
<div class="error-message"></div>
</div>
<!-- 提交按钮 -->
<div class="form-item">
<button type="submit" :disabled="isSubmitting">提交</button>
</div>
</form>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { vVerify } from '@cp-vuedir/core'
import { Notification } from '@arco-design/web-vue'
const formDate = reactive({
username: '',
password: '',
confirmPassword: ''
})
const isSubmitting = ref(false) // 提交按钮的加载状态
const hasErrors = ref(false) // 是否有错误
const formErrors = ref({}) // 表单错误信息
const delay = ref(1000) // 延迟校验时间
// 校验规则
const rules = {
username: [
{ required: true, message: '用户名不能为空' },
{ min: 3, max: 10, message: '用户名长度必须在 3 到 10 个字符之间' },
{
asyncValidator: (value: string) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(value !== 'admin' ? null : '用户名已存在')
}, 1000)
})
}
}
],
password: [
{ required: true, message: '密码不能为空' },
{ pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/, message: '密码必须包含字母和数字,且长度至少为 8 位' }
],
confirmPassword: [
{ required: true, message: '请再次输入密码' },
{
asyncValidator: (value: string) => {
return value === formDate.password ? null : '两次输入的密码不一致'
}
}
]
}
// 处理校验结果
const handleValidate = (event: CustomEvent) => {
const { isValid } = event.detail
hasErrors.value = !isValid // 更新是否有错误
}
// 提交表单
const handleSubmit = (e: Event) => {
e.preventDefault()
console.log(hasErrors.value)
isSubmitting.value = true // 显示加载状态
// 模拟提交逻辑
setTimeout(() => {
if (hasErrors.value) {
// 如果有错误,显示提交失败
Notification.error('提交失败,请检查表单错误')
} else {
// 如果没有错误,显示提交成功
Notification.success('提交成功')
}
isSubmitting.value = false // 隐藏加载状态
}, delay.value)
}
</script>
<style scoped>
.custom-form {
max-width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px solid #e5e5e5;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.form-item {
margin-bottom: 16px;
}
.form-item:last-child {
margin-bottom: 0;
}
.form-item label {
display: block;
margin-bottom: 4px;
}
.form-item input {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
.form-item .error-message {
color: #f53f3f;
font-size: 12px;
margin-top: 4px;
}
button {
width: 100%;
padding: 8px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
</style>
blur 情况下,单个校验表单每项
查看代码
vue
<template>
<form
:model="formDate"
v-verify:blur="{ ...rules, delay: delay }"
@submit="handleSubmit"
@validate="handleValidate"
class="custom-form"
>
<!-- 用户名 -->
<div class="form-item">
<label for="username">用户名</label>
<input type="text" id="username" name="username" v-model="formDate.username" placeholder="请输入用户名" />
<div class="error-message"></div>
</div>
<!-- 密码 -->
<div class="form-item">
<label for="password">密码</label>
<input type="password" id="password" name="password" v-model="formDate.password" placeholder="请输入密码" />
<div class="error-message"></div>
</div>
<!-- 确认密码 -->
<div class="form-item">
<label for="confirmPassword">确认密码</label>
<input
type="password"
id="confirmPassword"
name="confirmPassword"
v-model="formDate.confirmPassword"
placeholder="请再次输入密码"
/>
<div class="error-message"></div>
</div>
<!-- 提交按钮 -->
<div class="form-item">
<button type="submit" :disabled="isSubmitting">提交</button>
</div>
</form>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { vVerify } from '@cp-vuedir/core'
import { Notification } from '@arco-design/web-vue'
const formDate = reactive({
username: '',
password: '',
confirmPassword: ''
})
const isSubmitting = ref(false) // 提交按钮的加载状态
const hasErrors = ref(false) // 是否有错误
const formErrors = ref({}) // 表单错误信息
const delay = ref(1000) // 延迟校验时间
// 校验规则
const rules = {
username: [
{ required: true, message: '用户名不能为空' },
{ min: 3, max: 10, message: '用户名长度必须在 3 到 10 个字符之间' },
{
asyncValidator: (value: string) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(value !== 'admin' ? null : '用户名已存在')
}, 1000)
})
}
}
],
password: [
{ required: true, message: '密码不能为空' },
{ pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/, message: '密码必须包含字母和数字,且长度至少为 8 位' }
],
confirmPassword: [
{ required: true, message: '请再次输入密码' },
{
asyncValidator: (value: string) => {
return value === formDate.password ? null : '两次输入的密码不一致'
}
}
]
}
// 处理校验结果
const handleValidate = (event: CustomEvent) => {
const { field, isValid, errors } = event.detail
formErrors.value = { ...formErrors.value, ...errors } // 更新表单错误信息
hasErrors.value = Object.values(formErrors.value).every((error) => error === null) // 判断是否有错误
}
// 提交表单
const handleSubmit = (e: Event) => {
e.preventDefault()
isSubmitting.value = true // 显示加载状态
// 模拟提交逻辑
setTimeout(() => {
if (!hasErrors.value) {
// 如果有错误,显示提交失败
Notification.error('提交失败,请检查表单错误')
} else {
// 如果没有错误,显示提交成功
Notification.success('提交成功')
}
isSubmitting.value = false // 隐藏加载状态
}, delay.value)
}
</script>
<style scoped>
.custom-form {
max-width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px solid #e5e5e5;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.form-item {
margin-bottom: 16px;
}
.form-item:last-child {
margin-bottom: 0;
}
.form-item label {
display: block;
margin-bottom: 4px;
}
.form-item input {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
.form-item .error-message {
color: #f53f3f;
font-size: 12px;
margin-top: 4px;
}
button {
width: 100%;
padding: 8px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
</style>
结合高级用法
查看代码
vue
<template>
<form
:model="formDate"
v-verify="{ ...rules, delay: delay }"
@submit="handleSubmit"
@validate="handleValidate"
class="custom-form"
>
<!-- 用户名 -->
<div class="form-item">
<label for="username">用户名</label>
<input type="text" id="username" name="username" v-model="formDate.username" placeholder="请输入用户名" />
<div class="error-message"></div>
</div>
<!-- 密码 -->
<div class="form-item">
<label for="password">密码</label>
<input type="password" id="password" name="password" v-model="formDate.password" placeholder="请输入密码" />
<div class="error-message"></div>
</div>
<!-- 确认密码 -->
<div class="form-item">
<label for="confirmPassword">确认密码</label>
<input
type="password"
id="confirmPassword"
name="confirmPassword"
v-model="formDate.confirmPassword"
placeholder="请再次输入密码"
/>
<div class="error-message"></div>
</div>
<!-- 提交按钮 -->
<div class="form-item">
<button type="submit" :disabled="isSubmitting">提交</button>
</div>
</form>
</template>
<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { vVerify } from '@cp-vuedir/core'
import { Notification } from '@arco-design/web-vue'
const formDate = reactive({
username: '',
password: '',
confirmPassword: ''
})
const isSubmitting = ref(false) // 提交按钮的加载状态
const hasErrors = ref(false) // 是否有错误
const formErrors = ref({}) // 表单错误信息
const delay = ref(1000) // 延迟校验时间
// 校验规则
const rules = {
username: [
{ required: true, message: '用户名不能为空' },
{ min: 3, max: 10, message: '用户名长度必须在 3 到 10 个字符之间' },
{
asyncValidator: (value: string) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(value !== 'admin' ? null : '用户名已存在')
}, 1000)
})
}
}
],
password: [
{ required: true, message: '密码不能为空' },
{ pattern: /^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$/, message: '密码必须包含字母和数字,且长度至少为 8 位' }
],
confirmPassword: [
{ required: true, message: '请再次输入密码' },
{
asyncValidator: (value: string) => {
return value === formDate.password ? null : '两次输入的密码不一致'
}
}
]
}
// 处理校验结果
const handleValidate = (event: CustomEvent) => {
const { field, isValid, errors } = event.detail
formErrors.value = { ...formErrors.value, ...errors } // 更新表单错误信息
hasErrors.value = Object.values(formErrors.value).every((error) => error === null) // 判断是否有错误
}
// 提交表单
const handleSubmit = (e: Event) => {
e.preventDefault()
isSubmitting.value = true // 显示加载状态
// 模拟提交逻辑
setTimeout(() => {
if (!hasErrors.value) {
// 如果有错误,显示提交失败
Notification.error('提交失败,请检查表单错误')
} else {
// 如果没有错误,显示提交成功
Notification.success('提交成功')
}
isSubmitting.value = false // 隐藏加载状态
}, delay.value)
}
</script>
<style scoped>
.custom-form {
max-width: 400px;
margin: 0 auto;
padding: 20px;
border: 1px solid #e5e5e5;
border-radius: 8px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.form-item {
margin-bottom: 16px;
}
.form-item:last-child {
margin-bottom: 0;
}
.form-item label {
display: block;
margin-bottom: 4px;
}
.form-item input {
width: 100%;
padding: 8px;
border: 1px solid #ccc;
border-radius: 4px;
}
.form-item .error-message {
color: #f53f3f;
font-size: 12px;
margin-top: 4px;
}
button {
width: 100%;
padding: 8px;
background-color: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-weight: 500;
}
button:disabled {
background-color: #ccc;
cursor: not-allowed;
}
</style>
API
属性名 | 说明 | 类型 | 是否必选 | 默认值 |
---|---|---|---|---|
:mode | 指定校验触发的方式,可选值:submit、blur。默认为 submit 和 blur 两种都支持 | string | null | |
...rules | 组件内部定义规则要求 | object | rules | |
@validate | 校验结果回调函数,返回校验结果 isValid 和 errors | function | null | |
delay | 校验延迟时间,单位毫秒 | number | 1000 |
注意事项
注意
- 该指令只能用于
form
标签。 v-verify
支持submit
和blur
两种触发方式,默认为submit
和blur
,blur
事件触发时,只会校验当前获得焦点的元素,不会校验整个表单。v-verify
目前每个校验规则只有以下属性:required
: 是否必填。min
: 最小长度。max
: 最大长度。pattern
: 正则表达式。message
: 自定义错误提示信息。asyncValidator
: 异步校验函数。- 校验结果会通过
validate
事件传递回组件。事件详情包含isValid
(是否校验通过)和errors
(错误信息)。
警告
rules
中,有自定义校验函数要用到其他input
的value
,请使用v-model
绑定值,否则会报错(结合高级用法代码中的确认密码有使用示例)。