vee-validate与vue表单的🔥(火花)碰撞

2,516 阅读4分钟

vee-validate是一个针对表单相关功能的校验器器,内置了丰富的校验规则和错误提示,而且非常容易扩展,天然为vuejs而生,之前基本不做什么表单功能,最近有涉及相关功能的使用,特整理输出文档,以便需要的人士查看。

在这里插入图片描述

相关参考

官方文档:vee-validate.logaretm.com/v3/

githua: github.com/logaretm/ve…

项目接入

版本明确:

  1. 2.x版本主要是以指令和配置方式使用,如有需要可参考:codesandbox.io/s/y3504yr0l…
  2. 目前比较稳定较长使用的是 3.x.x的版本主要是支持 Vue 2.x和基于vue2的@vue/composition-api ,v3版本文档:vee-validate.logaretm.com/v3/guide/ba…
  3. 最新版本是4.x.x的仅支持 Vue 3.x

项目接入

安装

npmnpm install vee-validate --saveyarnyarn add vee-validate

引入

// app.js文件
// 提供的两个基础组件可以全局引入或者局部引入
import Vue from 'vue'
import {
    ValidationObserver,
    ValidationProvider,
    extend
} from 'vee-validate'

//全局注册

Vue.component('ValidationProvider', ValidationProvider)
Vue.component('ValidationObserver', ValidationObserver)
//单个校验 可以只使用就可以完成 ValidationProvider
//如果涉及整个表单块的校验,一般是需要 ValidationObserver 和 ValidationProvider结合
// ValidationProvider 主要是单个表单项的基础校验
// ValidationObserverl类似于整个表单的监听这,在表单整体提交时可以对表单内每一个设置校验规则的检测

// extend 是我们可以自定义或者扩展校验规则
// 添加自定义规则
// 手机号校验
extend('phone', {
    validate(value) {
        return (/^1[123456789]\d{9}$/.test(value))
    },
    message: '请输入正确的手机号码'
})

其实我们传统的表单校验和规则基本上是明确的,vee-validate 本身也内置了基本的规则可以方便我们使用,同时支持语言设置功能,提供了进一步的便利,如下:

进阶引入

// app.js文件
// 提供的两个基础组件可以全局引入或者局部引入
import Vue from 'vue'
import {
    ValidationObserver,
    ValidationProvider,
    extend,
   localize
} from 'vee-validate'
import zh from 'vee-validate/dist/locale/zh_CN.json'
import { required, email, integer, min_value } from 'vee-validate/dist/rules' // 按需引入已有的规则// 设置语言为中文,默认为英文
localize('zh', zh)

//全局注册
Vue.component('ValidationProvider', ValidationProvider)
Vue.component('ValidationObserver', ValidationObserver)
//单个校验 可以只使用就可以完成 ValidationProvider
//如果涉及整个表单块的校验,一般是需要 ValidationObserver 和 ValidationProvider结合
// ValidationProvider 主要是单个表单项的基础校验
// ValidationObserverl类似于整个表单的监听这,在表单整体提交时可以对表单内每一个设置校验规则的检测

// extend 是我们可以自定义或者扩展校验规则
// 添加内置规则
extend('email', email) // 邮箱校验
// 添加自定义规则
// 手机号校验
extend('phone', {
    validate(value) {
        return (/^1[123456789]\d{9}$/.test(value))
    },
    message: '请输入正确的手机号码'
})

 vee-validate 内置了如下规则,可参考: github.com/logaretm/ve…

import { extend } from 'vee-validate'
import * as rules from 'vee-validate/dist/rules'
// rules: {alpha:xx,alpha_dash:xx,alpha_num:xx……}
Object.keys(rules).forEach(rule => {
  extend(rule, rules[rule])
})
// Object.keys(rules) 获得对象中全部的属性名称,
// 并以数组返回["alpha", "alpha_dash", "alpha_num", ……]
// extend(rule, rules[rule]) 完成每个内置校验规则的注册操作Available Rules

基础使用

<template>
<ValidationProvider rules="phone|email" v-slot="{ errors }">
               <input v-model="email" type="text"> <span>{{ errors[0] }}</span>

</ValidationProvider></template>

// test.vue组件内使用 局部注册
import { ValidationProvider, ValidationObserver, extend } from "vee-validate"; //自定义校验的方法
extend("required", {
  ...required,
  message: "此项必填",
});
export default {
  components: {
    ValidationProvider,
    ValidationObserver,
  },
  data() {
    
};
</script>

<style lang="less" scoped>
.validate-span {
  font-size: 12px;
  color: tomato;
}
/deep/.el-select.error-txt .el-input__inner {
  border: 1px solid tomato !important;
}
</style>

注意:xx.vue中的rules="phone|email" 对应app.js中添加的规则phone / email 。VeeValidate默认没有规则。

如何提示语义化的错误呢,如果要校验手机号,就提示手机号格式错误,如果要校验邮箱,就提示邮箱错误,校验规则支持 变量提示

<ValidationProvider rules="required" name="邮箱" v-slot="{ errors }">
  <input v-model="email" type="text">
  <span>{{ errors[0] }}</span>
</ValidationProvider>

extend('required', {
  ...required,
  message: '{_field_}不能为空'
})

给校验规则传参

单个参数

<ValidationProvider rules="required|len:6" name="密码" v-slot="{ errors }">
  <input v-model="pwd" type="text">
  <span>{{ errors[0] }}</span>
</ValidationProvider>


extend('required', {
  ...required,
  message: '{_field_}不能为空'
})
extend('len', {
  validate (value, args) {
    return value.length === parseInt(args.leng)
  },
  params: ['leng'],
  message: '{_field_}长度为6'
})

多个参数

<ValidationProvider rules="required|range:4,6" name="密码" v-slot="{ errors }">
  <input v-model="pwd" type="text">
  <span>{{ errors[0] }}</span>
</ValidationProvider>

extend('range', {
  validate (value, args) {
    return value.length >= parseInt(args.min) && value.length <= parseInt(args.max)
  },
  params: ['min', 'max'],
  message: '{_field_}长度为4-6'
})

结合多参数更具体的提示:

extend('minmax', {
    validate(value, {
        min,
        max
    }) {
        return value.length >= min && value.length <= max;
    },
    params: ['min', 'max'],
    message: 'The {_field_} field must have at least {min} characters and {max} characters at most'
});

进阶使用

ValidationProvider使用

<van-cell-group>
	<!-- 表单域校验,通过 ValidationProvider 对被校验的项目做包围
         name:校验失败,提示当前项目名称,定义校验字段名称,用作错误提示使用
         rules:设置校验规则,required 必填
         v-slot: 接收"作用域插槽"数据,即校验失败错误信息
		注意:当前这个地方只能使用v-slot(使用slot-scope,页面没有效果)-->
	<ValidationProvider name="手机号" rules="required" v-slot="{ errors }">
		<!-- 把校验的错误信息展示出来,error-message:显示校验失败的错误信息 -->
		<van-field v-model="loginForm.mobile" type="text" placeholder="请输入手机号码"
                   label="手机号" required clearable :error-message="errors[0]" />
		<!-- van-field通过:error-message接收、显示校验错误信息 -->
	</ValidationProvider>
	<ValidationProvider name="验证码" rules="required" v-slot="{ errors }">
		<van-field v-model="loginForm.code" type="password" placeholder="请输入验证码"
                   label="验证码" required clearable :error-message="errors[0]" />
		<!-- 命名插槽应用,提示相关按钮,是要给van-field组件内部的slot去填充的 -->
		<van-button slot="button" size="small" type="primary">发送验证码</van-button>
	</van-field>
</ValidationProvider>undefined</van-cell-group>
……

v-slot说明:

之前使用slot-scope接收子组件作用域插槽的数据信息,在vue新版本中,可以通过v-slot接收作用域插槽数据,格式就是 v-slot="数据名称"slot-scope="stData" {{stData.errors[0]}}表现具体校验失败错误信息。
形式上:v-slot="stData" slot-scope="stData"就是一样的。

v-slot="{errors}" 对象解构赋值 errors[0]
v-slot="stData" {{stData.errors[0]}}

当前校验部分,errors[0] 可以访问到校验失败的错误信息,固定用法。

v-slot和slot-scope的区别

  • v-slot 只能被用在组件标签或template标签身上

  • slot-scope 可以被应用在组件标签、普通html标签、template标签上

ValidationProvider -- Scoped Slot Props

ValidationProvider -- props

ValidationProvider -- methods

provider 实例上的验证。使用 refs 和公共方法 validate 以及 applyResult 使得这个过程变得轻而易举。

<template>
	<div>
		<ValidationProvider rules="required" ref="myinput">
			<VTextField slot-scope="{ errors }" v-model="value" :error-messages="errors" />
		</ValidationProvider>
		<v-btn @click="validateField('myinput')" >Submit</v-btn>
	</div>
</template>

export default {
    // ...
    methods: {
        validateField(field) {
            const provider = this.$refs[field];

            // 验证字段,但是不改变字段的状态
            provider.validate().then(
                // 改变状态
                provider.applyResult
            );
        }
    },
    // ..
};

ValidationObserver使用

ValidationObserver  -- Scoped Slot Props

由于ValidationObserver的solt插槽属性基本与验证提供者(ValidationProvider)一致,这里只挑一些重点内容。

Props

示例如下:

<ValidationObserver slim ref="form">
	<van-cell-group>
		<ValidationProvider name="手机号" rules="required|phone" v-slot="{ errors }" slim>
			<van-field
        v-model="form.phone"
        label="手机号"
        placeholder="请输入手机号"
        required
        :error-message="errors[0]"
      />
		</ValidationProvider>
		<ValidationProvider name="邮箱" rules="required|email" v-slot="{ errors }" slim>
			<van-field
        v-model="form.email"
        label="邮箱"
        placeholder="请输入邮箱"
        required
        :error-message="errors[0]"
      />
		</ValidationProvider>
		<ValidationProvider name="性别" rules="required" v-slot="{ errors }" slim :customMessages="{'required':'请选择{_field_}'}">
			<van-cell title="性别" required >
				<van-radio-group v-model="form.sex">
					<van-radio :name="0" class="mar-b-15">男</van-radio>
					<van-radio :name="1">女</van-radio>
				</van-radio-group>
				<p class="fc-red text-c">{{errors[0]}}</p>
			</van-cell>
		</ValidationProvider>
		<van-field
      v-model="form.resume"
      label="备注"
      placeholder="请输入备注"
      type="textarea"
      autosize rows="1"
    />
	</van-cell-group>
</ValidationObserver>
<van-button type="info" @click="onSubmit" block round>保存</van-button>

<script>
data() {
    return {
        form: {
            phone: '',
            email: '',
            sex: '',
            resume: ''
        }
    }
}
methods: {
    onSubmit() {
        this.$refs.form.validate().then(success => {
            // success结果返回布尔值
            if (!success) return
            // 处理请求

            this.$nextTick(() => {
                // 清除验证状态,需注意值不会清除要自己手动清除
                this.$refs.form.reset()
            })
        })
    }
}
</script>

slim:默认情况下,ValidationProviderValidationObserver组件渲染为span标签,设置slim则不会渲染,具体使用参考官方说明。

name:指定要在错误消息中使用的名称。就是用来替代模版里的{_field_}

rules:应用验证规则,多个规则用“|”符号隔开。

customMessages:自定义错误消息。将覆盖任何默认和已配置的消息。