Appearance
vee-validate
使用 VeeValidate 可以快速的进行 vue 项目的表单验证。
安装扩展
使用 yarn 或 npm 安装扩展包
- vee-validate 表单验证核心库
- vee-validate/rules 验证规则
- yup 支持定义链式声明的验证规则
yarn add vee-validate@next @vee-validate/rules yup @vee-validate/i18n
# 或者使用npm
npm install --save vee-validate@next @vee-validate/rules @vee-validate/i18n
组件方式
vee-validate 提供了组件方式进行验证,加快常用表单验证的开发效率
基本使用
使用扩展提供的 Form/Field/ErrorMessage
组件可以简化验证过程
- 组件 Field 中的label属性用于定义错误消息的表单名称
- 组件 Field 中的rules属性用于定义 验证规则
- 组件 Field 中的 validate-on-input 指 input 事件时验证,其他事件请查看事件文档
<script lang="ts" setup>
import { Form, Field, ErrorMessage } from 'vee-validate';
const validateEmail = (value: any) => {
return /@/.test(value) ? true : '邮箱格式错误'
}
const onSubmit = () => {
alert('验证通过时执行')
}
</script>
<template>
<Form @submit="onSubmit">
<Field name="email" :rules="validateEmail" label="帐号" :validate-on-input="true"/>
<ErrorMessage name="email" />
<hr />
<button>提交</button>
</Form>
</template>
插槽布局
下面是使用插槽来自定义验证布局
<Form>
<Field name="username" :rules="{ email: true }" :validate-on-input="true" #default="{ errorMessage, field }">
<input v-bind="field" type="text" />
<p>{{ errorMessage }}</p>
</Field>
<!-- <ErrorMessage name="username" /> -->
</Form>
验证规则
使用 @vee-validate/rules 提供的验证规则进行验证,可以减少我们写验证规则
defineRule
用于定义全局验证规则,然后在模板中使用
<script lang="ts" setup>
import { Form, Field, ErrorMessage, defineRule } from 'vee-validate';
import { required, email, regex, confirmed } from '@vee-validate/rules';
defineRule('required', required)
defineRule('email', email)
const onSubmit = () => {
alert('验证通过时执行,斑马兽 banmashou.com')
}
</script>
<template>
<Form @submit="onSubmit">
<Field name="email" :rules="{ required, email }" label="帐号" />
<ErrorMessage name="email" />
<hr />
<button>提交</button>
</Form>
</template>
组合 API
组合 API 即使用非组件的 JS 编程方式进行表单验证
单独定义
下面是为字段单独定义规则
- useField 的第一个参数为表单 name,会在表单提交事件中做为参数
<script lang="ts" setup>
import { Form, Field, ErrorMessage, defineRule, useField, useForm } from 'vee-validate';
function isEmail(value: any) {
return /@/.test(value) ? true : '斑马兽提示:邮箱格式错误'
}
const { errorMessage, value: email } = useField('fieldName', isEmail);
</script>
<template>
<input v-model="email" label="帐号" />
<h2>{{ errorMessage }}</h2>
</template>
提交表单
使用 handleSubmit 可以在验证通过时提交表单
- useField 的第一个参数为表单 name,会在表单提交事件中做为参数
<script lang="ts" setup>
import { useField, useForm } from 'vee-validate';
function isEmail(value: any) {
return /@/.test(value) ? true : '斑马兽提示:邮箱格式错误'
}
const { handleSubmit } = useForm()
const { errorMessage, value: email } = useField('fieldName', isEmail);
const onSubmit = handleSubmit(values => {
console.log(values);
alert('验证通过时执行')
})
</script>
<template>
<form @submit="onSubmit">
<input v-model="email" label="帐号" />
<h2>{{ errorMessage }}</h2>
<button>提交</button>
</form>
</template>
集中声明
下面为表单字段集中定义验证规则
<script lang="ts" setup>
import { useField, useForm } from 'vee-validate';
const rules = {
email(value: any) {
return /@/.test(value) ? true : '斑马兽提示:邮箱格式错误'
},
password(value: any) {
return value ? true : '密码不能为空'
}
}
useForm({
validationSchema: rules
})
const { errorMessage: mailError, value: email } = useField('email');
const { errorMessage: passwordError, value: password } = useField('password');
</script>
<template>
<input v-model="email" label="帐号" />
<h2>{{ mailError }}</h2>
<hr />
<input type="password" v-model="password" />
<h2>{{ passwordError }}</h2>
</template>
验证规则
验证规则可以是字符串、对象、函数或 yup 架构:
// 使用' defineRule '的全局定义规则,类似laravel的语法
useField('password', 'required|min:8');
// 全局定义的规则对象
useField('password', { required: true, min: 8 });
// 验证函数
useField('password', value => {
if (!value) {
return 'password is required';
}
if (value.length < 8) {
return 'password must be at least 8 characters long';
}
return true;
});
// Yup 验证
useField('password', yup.string().required().min(8));
中文消息
使用 @vee-validate/i18n 实现中文验证消息
<script lang="ts" setup>
import { defineRule, useField, useForm, configure } from 'vee-validate';
import { required, email, min } from '@vee-validate/rules'
import { localize } from '@vee-validate/i18n';
import zh_CN from '@vee-validate/i18n/dist/locale/zh_CN.json'
defineRule('required', required)
defineRule('email', email)
defineRule('min', min)
configure({
generateMessage: localize('zh_CN', zh_CN),
});
const { handleSubmit, errors } = useForm({
initialValues: {
account: '斑马兽@banmashou.com'
},
validationSchema: {
account: 'required|min:8|email'
}
})
const { errorMessage, value: account } = useField('account', {}, { label: '帐号' });
const onSubmit = handleSubmit(values => {
console.log(values);
alert('验证通过时执行')
})
</script>
<template>
<form @submit="onSubmit">
<input v-model="account" label="帐号" />
<h2>{{ errorMessage }}</h2>
<button>提交</button>
</form>
</template>
为了节省打包文件大小,语言包也可以使用网络加载
...
// import zh_CN from '@vee-validate/i18n/dist/locale/zh_CN.json'
loadLocaleFromURL('https://unpkg.com/@vee-validate/i18n@4.1.0/dist/locale/zh_CN.json');
configure({
generateMessage: localize('zh_CN'),
});
...
Yup
Yup 是好用的支持链式声明的验证规则声明工具,更多验证规则请查看 yup 文档
安装
yarn add yup
基本使用
<script lang="ts" setup>
import * as yup from 'yup';
import { useField, useForm } from 'vee-validate';
const { handleSubmit } = useForm({
initialValues: {
account: '斑马兽'
},
validationSchema: {
account: yup.string().email('邮箱输入错误')
}
})
const { errorMessage, value: account } = useField('account', {});
const onSubmit = handleSubmit(values => {
console.log(values);
alert('验证通过时执行')
})
</script>
<template>
<form @submit="onSubmit">
<input v-model="account" label="帐号" />
<h2>{{ errorMessage }}</h2>
<button>提交</button>
</form>
</template>
业务封装
上面介绍了验证的使用方式,但是如果每个组件都这样声明,显然很麻烦。我们可以将公共的业务提取出来。
文件结构
下面是我们提取为插件的文件结构
src/plugins
├── validate
│ ├── index.ts
│ └── yup.ts
yup.ts
import * as yup from 'yup';
//定义中文提示信息
yup.setLocale({
mixed: {
required: '${label}不能为空'
},
string: {
email: '邮箱格式错误',
min: '${label}不能少于 ${min} 位',
max: '不能大于 ${max} 位'
},
number: {
min: '${label}}不能少于 ${min} ',
max: '不能大于 ${max} '
}
});
export default yup
index.ts
import yup from './yup'
import rules from '@vee-validate/rules'
import * as veeValidate from 'vee-validate'
import { localize } from '@vee-validate/i18n'
import zh_CN from '@vee-validate/i18n/dist/locale/zh_CN.json'
//配置
veeValidate.configure({
//中文支持
generateMessage: localize('zh_CN', zh_CN),
//input事件时验证
validateOnInput: true,
})
//批量定义规则
Object.keys(rules).forEach((key) => {
veeValidate.defineRule(key, rules[key])
})
//指定设置useField
const useFields = (fields: string[]) => {
fields.forEach((field) => veeValidate.useField(field))
}
export default { yup, ...veeValidate, useFields }
实际使用
<script lang="ts" setup>
import v from '@/plugins/validate'
const { handleSubmit, errors } = v.useForm({
initialValues: {
account: '斑马兽',
password: ''
},
validationSchema: {
account: { email: true },
password: v.yup.string().min(3).label('密码')
}
})
const { value: account } = v.useField('account', {}, { label: 'HI:' });
const { value: password } = v.useField('password', {});
const onSubmit = handleSubmit(values => {
console.log(values);
alert('验证通过时执行')
})
</script>
<template>
<form @submit="onSubmit">
<input v-model="account" />
<h2>{{ errors.account }}</h2>
<input v-model="password" />
<h2>{{ errors.password }}</h2>
<button>提交</button>
</form>
</template>
也可以使用 useForm 的属性 values
与values
简化操作
<script lang="ts" setup>
import v from '@/plugins/validate'
const { useForm, yup, useFields } = v
const schema =yup.object({
account: v.yup.string().email(),
password: v.yup.string().min(3).label('密码')
});
const { handleSubmit, errors,values } = useForm({
initialValues: {
account: '斑马兽',
password: ''
},
validationSchema:schema
})
//批量设置useField()响应
useFields(Object.keys(schema.fields))
const onSubmit = handleSubmit(values => {
console.log(values);
alert('验证通过时执行')
})
</script>
<template>
<form @submit="onSubmit">
<input v-model="values.account" />
<h2>{{ errors.account }}</h2>
<input v-model="values.password" />
<h2>{{ errors.password }}</h2>
<button>提交</button>
</form>
</template>