vue项目中使用vee-validate表单验证

67 篇文章 7 订阅
25 篇文章 2 订阅

官方文档 https://vee-validate.logaretm.com/v4/  支持vue3.0

npm https://www.npmjs.com/package/vee-validate

1.安装包

npm i vee-validate@4.0.3

 2. 引入 组件 

import { Form, Field } from 'vee-validate'

components:{Form, Field}

3.结构

form就是表单 field就是表单项 ===input

<Form>
      <Field v-model="formData.mobile" name="mobile" type="text" placeholder="请输入手机号" />
      <Field v-model="formData.password" name="password" type="password" placeholder="请输入密码" />
</Form>

4.定义校验规则 

整体用一个对象包起来,每条规则就是一个函数。具体格式如下:

  • 参数1:是要验证的值,参数2:是验证对象{field, form}

  • 返回值:true表示通过验证,返回字符串表示校验错误。

    // 定义校验规则
    const schema = {
      account  (value) {
        if (!value) {
          return '用户名不能为空,请检查!'
        }
        return true
      },
      mobile (value) {
        if (!value) return '请输入手机号'
        if (!/^1[3-9]\d{9}$/.test(value)) return '手机号格式错误'
        return true
      },
      password (value) {
        if (!value) return '请输入密码'
        if (!/\d{6}$/.test(value)) return '密码格式错误'
        return true
      },
      isAgree (value) {
        return value || '不答应可不行'
      }
    }

5.使用规则

form:
ref: 引用;后边手动兜底校验要使用
validation-schema: 用来指定校验规则(这里的规则) 
v-slot: 作用域插槽,如果校验失败,errors中会保存校验失败的结果

 Field:

v-model:双向绑定数据项
name:指定要校验的字段
:class="{error:errors.mobile}" 如果校验失败,就补充error类
动态绑定class用来约定错误发生时的样子

<Form ref="target" :validation-schema="schema" v-slot="{errors}">
  		<!-- 省略其他 ... -->
      <Field 
             v-model="formData.mobile" 
             type="text" 
             name="mobile"
             placeholder="请输入手机号" 
             :class="{error:errors.mobile}"
       />
  		<!-- 约定显示校验错误结果 -->
       <div class="error" v-if="errors.mobile">{{errors.mobile}}</div>
  
       <!-- 省略其他 ... -->
</Form>

 6.手动兜底校验

    const login = () => {
      target.value.validate().then((res) => {
        console.log('表单校验结果', res)
      })
    }

7.总体代码

1.    用Form去替换原来的form, 用Field去替换原input元素
            1.    Form中要使用:ref, validation-schema, v-slot
            2.    Field中设置v-model, name, class
2.     补充dom结构来存放校验错误提示(在element, vant等组件库中,我们是不需要写的)
3.    用`as` 来特殊处理xtxCheckBox组件

<template>
  <div class="account-box">
    <!-- 登录方式切换 -->
    <div class="toggle">
      <a
        href="javascript:;"
        v-if="isMsgLogin"
        @click="isMsgLogin = !isMsgLogin"
      >
        <i class="iconfont icon-user"></i> 使用账号登录
      </a>
      <a href="javascript:;" v-else @click="isMsgLogin = !isMsgLogin">
        <i class="iconfont icon-msg"></i> 使用短信登录
      </a>
    </div>
    <!--
      ref: 引用;后边手动兜底校验要使用
      validation-schema: 用来指定校验规则(这里的规则)
      v-slot: 作用域插槽,如果校验失败,errors中会保存校验失败的结果
    -->
    <Form
      class="form"
      ref="target"
      :validation-schema="schema"
      v-slot="{ errors }"
    >
      <!-- 使用账号登录 -->
      <template v-if="!isMsgLogin">
        <div class="form-item">
          <div class="input">
            <i class="iconfont icon-user"></i>
            <!--
              Field: v-model:双向绑定数据项
                    name:指定要校验的字段
                    :class="{error:errors.mobile}" 如果校验失败,就补充error类
              动态绑定class用来约定错误发生时的样子 -->
            <!-- <input type="text" placeholder="请输入用户名" /> -->
            <Field
              v-model="form.account"
              name="account"
              type="text"
              placeholder="请输入用户名"
              :class="{error:errors.account}"
            ></Field>
          </div>
           <div class="error" v-if="errors.account">{{errors.account}}</div>
          <!-- <div class="error"><i class="iconfont icon-warning" />请输入手机号</div> -->
        </div>
        <div class="form-item">
          <div class="input">
            <i class="iconfont icon-lock"></i>
             <Field
              v-model="form.password"
              name="password"
              type="text"
              placeholder="请输入密码 长度为6位"
              :class="{error:errors.password}"
            ></Field>
            <!-- <input type="password" placeholder="请输入密码" /> -->
          </div>
           <div class="error" v-if="errors.password">{{errors.password}}</div>
        </div>
      </template>

      <!-- 使用验证码登录 -->
      <template v-else>
        <div class="form-item">
          <div class="input">
            <i class="iconfont icon-user"></i>
            <!-- <input type="text" placeholder="请输入手机号" /> -->
             <Field
              v-model="form.mobile"
              name="mobile"
              type="text"
              placeholder="请输入用户名"
              :class="{error:errors.mobile}"
            ></Field>
          </div>
          <div class="error" v-if="errors.mobile">{{errors.mobile}}</div>
        </div>
        <div class="form-item">
          <div class="input">
            <i class="iconfont icon-code"></i>
            <input type="password" placeholder="请输入验证码" />
            <span class="code">发送验证码</span>
          </div>
        </div>
      </template>

      <div class="form-item">
        <div class="agree">
          <Field as="XtxCheckbox" name="isAgree" v-model="form.isAgree" />
            <span>我已同意</span>
            <a href="javascript:;">《隐私条款》</a>
            <span>和</span>
            <a href="javascript:;">《服务条款》</a>
        </div>
           <div class="error" v-if="errors.isAgree"><i class="iconfont icon-warning" />{{errors.isAgree}}</div>
      </div>
      <a href="javascript:;" @click="login" class="btn">登录</a>
    </Form>
    <div class="action">
      <!-- qq登录 -->
      <img
        src="https://qzonestyle.gtimg.cn/qzone/vas/opensns/res/img/Connect_logo_7.png"
        alt=""
      />
      <div class="url">
        <a href="javascript:;">忘记密码</a>
        <a href="javascript:;">免费注册</a>
      </div>
    </div>
  </div>
</template>
<script>
import { ref, reactive } from 'vue'
import { Form, Field } from 'vee-validate'
export default {
  components: { Form, Field },
  setup () {
    //   是否短信登录
    const isMsgLogin = ref(false)
    // 定义校验规则
    const schema = {
      account  (value) {
        if (!value) {
          return '用户名不能为空,请检查!'
        }
        return true
      },
      mobile (value) {
        if (!value) return '请输入手机号'
        if (!/^1[3-9]\d{9}$/.test(value)) return '手机号格式错误'
        return true
      },
      password (value) {
        if (!value) return '请输入密码'
        if (!/\d{6}$/.test(value)) return '密码格式错误'
        return true
      },
      isAgree (value) {
        return value || '不答应可不行'
      }
    }

    const target = ref(null)

    // 表单对象数据
    const form = reactive({
      isAgree: false,
      account: null,
      password: null,
      mobile: null,
      code: null
    })
    // 登陆时自定义校验
    const login = () => {
      target.value.validate().then((res) => {
        console.log('表单校验结果', res)
      })
    }
    return { isMsgLogin, schema, target, form, login }
  }
}
</script>
<style lang="less" scoped>
// 账号容器
.account-box {
  .toggle {
    padding: 15px 40px;
    text-align: right;
    a {
      color: @xtxColor;
      i {
        font-size: 14px;
      }
    }
  }
  .form {
    padding: 0 40px;
    &-item {
      margin-bottom: 28px;
      .input {
        position: relative;
        height: 36px;
        > i {
          width: 34px;
          height: 34px;
          background: #cfcdcd;
          color: #fff;
          position: absolute;
          left: 1px;
          top: 1px;
          text-align: center;
          line-height: 34px;
          font-size: 18px;
        }
        input {
          padding-left: 44px;
          border: 1px solid #cfcdcd;
          height: 36px;
          line-height: 36px;
          width: 100%;
          &.error {
            border-color: @priceColor;
          }
          &.active,
          &:focus {
            border-color: @xtxColor;
          }
        }
        .code {
          position: absolute;
          right: 1px;
          top: 1px;
          text-align: center;
          line-height: 34px;
          font-size: 14px;
          background: #f5f5f5;
          color: #666;
          width: 90px;
          height: 34px;
          cursor: pointer;
        }
      }
      > .error {
        position: absolute;
        font-size: 12px;
        line-height: 28px;
        color: @priceColor;
        i {
          font-size: 14px;
          margin-right: 2px;
        }
      }
    }
    .agree {
      a {
        color: #069;
      }
    }
    .btn {
      display: block;
      width: 100%;
      height: 40px;
      color: #fff;
      text-align: center;
      line-height: 40px;
      background: @xtxColor;
      &.disabled {
        background: #cfcdcd;
      }
    }
  }
  .action {
    padding: 20px 40px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    .url {
      a {
        color: #999;
        margin-left: 10px;
      }
    }
  }
}
</style>

8.校验复用 

如果还有其它校验和上面的一样 我们可以采用抽里成一个js文件进行复用

validate.js

import { userCheckAccount } from '@/api/user'
export const account = (value) => {
  if (!value) {
    return '用户名不能为空,请检查!'
  }
  return true
}
export const mobile = (value) => {
  if (!value) return '请输入手机号'
  if (!/^1[3-9]\d{9}$/.test(value)) return '手机号格式错误'
  return true
}
export const password = (value) => {
  if (!value) return '请输入密码'
  if (!/\d{6}$/.test(value)) return '密码格式错误,长度为6位'
  return true
}
export const isAgree = (value) => {
  return value || '不答应可不行'
}
export const code = (value) => {
  if (!value) return '请输入验证码'
  if (!/\d{6}$/.test(value)) return '验证码格式错误'
  return true
}

export const accountApi = async (value) => {
  if (!value) return '请输入用户名'
  if (!/^[a-zA-Z]\w{5,19}$/.test(value)) return '字母开头且6-20个字符'
  // 服务端校验
  // 解构结果
  const { result } = await userCheckAccount(value)
  if (result.valid) return '用户名已存在'
  return true
}

export const rePassword = (value, { form }) => {
  if (!value) return '请输入密码'
  if (!/^\w{6,24}$/.test(value)) return '密码是6-24个字符'
  // 校验密码是否一致  form表单数据对象
  if (value !== form.password) return '两次输入的密码不一致'
  return true
}

引入校验

import { account, isAgree, password, mobile } from '@/utils/validate'

setup(){
    const schema = {
      account, mobile, password, isAgree
    }
}

9.总结

  1. 定义表单数据和相应校验规格

  2. 在模板中:

    • 用Form组件包起要校验的字段,并设置(3件事)

      <Form ref="target" :validation-schema="mySchema" v-slot="{errors}" autocomplete="off">

    • 用Field组件替换表单元素,并设置(3件事)

      <Field v-model="formData.mobile" name="mobile" :class="{err:errors.mobile} />

    • 补充额外的错误设置

      <div v-if="errors.mobile" class="error">{{errors.mobile}}</div>

  3. 表单提交时的手动兜底校验

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 3 和 VeeValidate 是两个独立的库,可以一起使用来进行验证。下面是一些关于 Vue 3 和 VeeValidate 的基本信息: 1. Vue 3:Vue 3 是一款流行的 JavaScript 框架,用于构建用户界面。它提供了一套简洁的语法和强大的功能,使开发者可以轻松构建交互式的前端应用程序。 2. VeeValidate:VeeValidate 是一个基于 Vue.js 的验证库。它提供了一组强大的验证规则和错误消息处理机制,方便开发者对进行验证和提示用户错误。 在 Vue 3 使用 VeeValidate,你需要按照以下步骤进行设置: 1. 安装 VeeValidate: ``` npm install vee-validate@next ``` 2. 在你的 Vue 3 项目导入 VeeValidate: ```javascript import { createApp } from 'vue'; import { createRouter, createWebHistory } from 'vue-router'; import { createI18n } from 'vue-i18n'; import { ValidationProvider, extend } from 'vee-validate'; import { required, email } from '@vee-validate/rules'; // 添加验证规则 extend('required', required); extend('email', email); const app = createApp(App); const router = createRouter({ history: createWebHistory(), routes, }); const i18n = createI18n({ locale: 'en', messages: { en: { validation: { required: 'This field is required.', email: 'Please enter a valid email address.', }, }, }, }); app.use(router); app.use(i18n); app.component('ValidationProvider', ValidationProvider); app.mount('#app'); ``` 3. 在你的 Vue 3 组件使用 VeeValidate: ```vue <template> <ValidationProvider v-slot="{ errors }" rules="required|email" name="email"> <input v-model="email" type="text" placeholder="Email"> <span>{{ errors[0] }}</span> </ValidationProvider> </template> <script> import { ref } from 'vue'; export default { name: 'MyForm', setup() { const email = ref(''); return { email, }; }, }; </script> ``` 通过以上步骤,你可以在 Vue 3 使用 VeeValidate 来进行验证。你可以根据自己的需要添加其他验证规则和自定义错误消息。希望对你有所帮助!如果还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值