vee-validate表单验证步骤

675 阅读2分钟
  1. 先下载包名

yarn add vee-validate

npm install vee-validate --save

  1. 导入 Form Field 组件将 form 和 input 进行替换,需要加上name用来校验规则函数
  2. Field需要使用v-modle进行数据绑定,字段名称最好和后台发送字段保持一致,
  3. 定义Field的name属性指定的校验规则函数, 在Form组件上使用validation-schema接受定义好的校验规则对象
  4. Field 的 as 属性可以指定为其他标签,也可指定为组件。 但是组件需要支持 v-model 否则校验不会触发。
  5. Form组件提供了一个 resetForm 函数,可以清除校验结果
  6. 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)
  }
}