vue项目中使用vee-validate表单验证
Posted 奥特曼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue项目中使用vee-validate表单验证相关的知识,希望对你有一定的参考价值。
官方文档 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
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 '密码格式错误'
return true
}
export const isAgree = (value) => {
return value || '不答应可不行'
}
引入校验
import { account, isAgree, password, mobile } from '@/utils/validate'
setup(){
const schema = {
account, mobile, password, isAgree
}
}
以上是关于vue项目中使用vee-validate表单验证的主要内容,如果未能解决你的问题,请参考以下文章