- 先下载包名
yarn add vee-validate
npm install vee-validate --save
- 导入 Form Field 组件将 form 和 input 进行替换,需要加上name用来校验规则函数
- Field需要使用v-modle进行数据绑定,字段名称最好和后台发送字段保持一致,
- 定义Field的name属性指定的校验规则函数, 在Form组件上使用validation-schema接受定义好的校验规则对象
Field的as属性可以指定为其他标签,也可指定为组件。 但是组件需要支持 v-model 否则校验不会触发。- Form组件提供了一个 resetForm 函数,可以清除校验结果
- Form组件提供了一个 validate 函数作为整体表单验证,返回的是一个promise
<Form class="form" :validation-schema="mySchema" v-slot="{errors}" ref="target" autocomplete="off">
<template v-if="!isMsgLogin">
<div class="form-item">
<div class="input">
<i class="iconfont icon-user"></i>
<Field v-model="form.account" type="text" name="account" placeholder="请输入用户名或手机号" />
</div>
<!-- 这里是错误信息提示,必须在Form组件上使用插槽结构出来errors对象 -->
<!-- 错误提示 -->
<div class="error" v-if="errors.account"><i class="iconfont icon-warning" />{{ errors.account }}</div>
</div>
<div class="form-item">
<div class="input">
<i class="iconfont icon-lock"></i>
<Field type="password" v-model="form.password" name="password" placeholder="请输入密码" />
</div>
<!-- 错误提示 -->
<div class="error" v-if="errors.password"><i class="iconfont icon-warning" />{{ errors.password }}</div>
</div>
</template>
<template v-else>
<div class="form-item">
<div class="input">
<i class="iconfont icon-user"></i>
<Field type="text" v-model="form.mobile" name="mobile" placeholder="请输入手机号" />
</div>
<!-- 错误提示 -->
<div class="error" v-if="errors.mobile"><i class="iconfont icon-warning" />{{ errors.mobile }}</div>
</div>
<div class="form-item">
<div class="input">
<i class="iconfont icon-code"></i>
<Field type="text" name="code" v-model="form.code" placeholder="请输入验证码" />
<span class="code">发送验证码</span>
</div>
<!-- 错误提示 -->
<div class="error" v-if="errors.code"><i class="iconfont icon-warning" />{{ errors.code }}</div>
</div>
</template>
<div class="form-item">
<div class="agree">
<!-- XtxCheckBox是复选框组件 需要使用as关键进行绑定 -->
<Field as="XtxCheckbox" name="isAgree" v-model="form.isAgree"/>
<span>我已同意</span>
<a href="javascript:;">《隐私条款》</a>
<span>和</span>
<a href="javascript:;">《服务条款》</a>
</div>
</div>
<a href="javascript:;" class="btn" @click="onLogin">登录</a>
</Form>
<script>
import { reactive, ref, watch } from 'vue'
import { Form, Field } from 'vee-validate'
// 引入校验规则
import schema from '@/utils/vee-validate-schema'
export default {
name: 'LoginForm',
components: {
Form,
Field
},
setup () {
// 表单数据绑定
const isMsgLogin = ref(false)
const form = reactive({
isAgree: true,
account: null,
password: null,
mobile: null,
code: null
})
// 定义校验规则
const mySchema = {
account: schema.account,
password: schema.password,
mobile: schema.mobile,
code: schema.code
}
// 每次切换登录模式需要清空表单验证与v-model的数据
// 需要ref获取组件实例 用来调用清空方法
const target = ref(null)
watch(isMsgLogin, () => {
form.account = null
form.password = null
form.mobile = null
form.code = null
// Form组件中提供了 resetForm() 函数可以清空表单验证规则
target.value.resetForm()
})
// 整体表单验证 Form组件中提供了 validate函数可以进行整体校验
const onLogin = async () => {
const isOk = await target.value.validate()
// isOk 中有一个valid属性通过是true否则false 进行判断发起业务请求
if(isOk.valid){
// 此处发起请求
}
}
return { isMsgLogin, form, mySchema, target, onLogin }
可以在utils中定义校验规则
// 定义校验规则提供给vee-validate组件使用
export default {
// 校验account
account (value) {
// value是将来使用该规则的表单元素的值
// 1. 必填
// 2. 6-20个字符,需要以字母开头
// 如何反馈校验成功还是失败,返回true才是成功,其他情况失败,返回失败原因。
if (!value) return '请输入用户名'
if (!/^[a-zA-Z]\w{5,19}$/.test(value)) return '字母开头且6-20个字符'
return true
},
password (value) {
if (!value) return '请输入密码'
if (!/^\w{6,24}$/.test(value)) return '密码是6-24个字符'
return true
},
mobile (value) {
if (!value) return '请输入手机号'
if (!/^1[3-9]\d{9}$/.test(value)) return '手机号格式错误'
return true
},
code (value) {
if (!value) return '请输入验证码'
if (!/^\d{6}$/.test(value)) return '验证码是6个数字'
return true
},
isAgree (value) {
if (!value) return '请勾选同意用户协议'
return true
},
// value就是表单输入框的内容
async accountCheck (value) {
if (!value) return '请输入用户名'
if (!/^[a-zA-Z]\w{5,19}$/.test(value)) return '字母开头且6-20个字符'
// 向后端发起请求,判断用户名是否存在
const { result } = await userAccountCheck(value)
if (result.valid) return '用户名已存在'
return true
},
// form中可以拿到表单数据
rePassword (value, { form }) {
if (!value) return '请输入密码'
if (!/^\w{6,24}$/.test(value)) return '密码是6-24个字符'
if (value !== form.password) return '两次密码不一致'
return true
},
}
手机短信登录逻辑(使用vee-validate单独验证表单)
const send = async () => {
// 1. 首先使用vee-validate验证 没输入手机号不允许点击发送短信
// 这样验证返回的是错误提示字符串
const valid = await mySchema.mobile(form.mobile)
if (valid === true) {
console.log('验证通过')
} else {
// 失败,使用vee的错误函数显示错误信息 setFieldError(字段,错误信息)
target.value.setFieldError('mobile', valid)
}
}