【Vue+ElementUI】表单校验(二)——动态表单项

Vuerify
是一个简单轻量的数据校验插件。内置基础的校验规则和错误提示。可自定义规则,规则类型支持正则、函数或者字符串。校验规则可全局注册也可以组件内注册。插件会给
vm 添加 $vuerify 对象,同时 watch 数据并校验合法性,如果有错误会存入
vm.$vuerify.$errors。

导入插件的步骤:

由于项目需要,开始用Vue.js+ElementUI来开发前端页面,今天的问题是,如果在Form表单校验中使用自定义方法?如果做后台校验(需要校验数据唯一性)?

Element中表单验证的基本方法可参照
官方说明

这节我们为大家介绍 Vue.js 表单上的应用。

安装

  1. 将jquery的原始文件和插件文件jquery.validate.js导入到工程中
  2. 编写js代码对表单进行验证
  3. 表单验证的格式:

最简单的Form表单校验:

<el-form :model="dynamicValidateForm" ref="dynamicValidateForm" label-width="100px" class="demo-dynamic">
  <el-form-item
    prop="email"
    label="邮箱"
    :rules="[
      { required: true, message: '请输入邮箱地址', trigger: 'blur' },
      { type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur,change' }
    ]"
  >
    <el-input v-model="dynamicValidateForm.email"></el-input>
  </el-form-item>
  <el-form-item
    v-for="(domain, index) in dynamicValidateForm.domains"
    :label="'域名' + index"
    :key="domain.key"
    :prop="'domains.' + index + '.value'"
    :rules="{
      required: true, message: '域名不能为空', trigger: 'blur'
    }"
  >
    <el-input v-model="domain.value"></el-input><el-button @click.prevent="removeDomain(domain)">删除</el-button>
  </el-form-item>
  <el-form-item>
    <el-button type="primary" @click="submitForm('dynamicValidateForm')">提交</el-button>
    <el-button @click="addDomain">新增域名</el-button>
    <el-button @click="resetForm('dynamicValidateForm')">重置</el-button>
  </el-form-item>
</el-form>

<script>
  export default {
    data() {
      return {
        dynamicValidateForm: {
          domains: [{
            value: ''
          }],
          email: ''
        }
      };
    },
    methods: {}
  }
</script>

你可以用 v-model 指令在表单控件元素上创建双向数据绑定。

npm i vuerify -S

//form.vue
//...
<el-form :model="form" :rules="rules" ref="form">
  <el-form-item label="编码" prop="code">
    <el-input v-model="form.code"></el-input>
  </el-form-item>
</el-form>

//js
<script>
export default {
  data () {
    return{
      form:{
        code: ''
      },
      rules:{
        code: [{ type: 'string', required: true, message: '请您完善此项', trigger: 'blur' }] // 必填校验
      }
  }
}
</script>

这是官方的一个例子,例子中包含一个表单,数据结构是:

图片 1

使用

$("form表单的选择器").validate(json数据格式);  //键值对 
  键:值({})
json数据格式:
{
      "rules":{
            表单项name值:校验规则,
            表单项name值:校验规则...  ...
      },
      "messages":{
            表单项name值:错误提示信息,
            表单项name值:错误提示信息...  ...
      }
}

这就完成一个最简单的校验,但是需求不是这么简单。

dynamicValidateForm:{
    email:'', // 基本属性
    domains:[] // 数组
}

v-model 会根据控件类型自动选取正确的方法来更新元素。

安装插件

其中:校验规则,可以是一个也可以是多个,如果是多个使用json格式

要做唯一性校验,那就要访问数据库了,那么就要考虑写一个自定义的方法了,于是,找到了validator:

“域名”表单项用了一个v-for来动态新增,需要注意的是:prop的值,常见的错误信息是“Error:
please transfer a valid prop path to form
item!”
,例子中使用的是‘domains.’ + index +
‘.value’
,其实和prop=”email”类似,用链式结构表示。

图片 2

import Vue from 'vue'
import Vuerify from 'vuerify'

Vue.use(Vuerify, /* 添加自定义规则 */)

常用校验规则如下:

图片 3

image

rules:{
  code:[
    // function(rule, value, callback, source, options)
    {validator:function(rule, value, callback){...}, trigger: 'blur'}
  ]

如果 ,数据的结构是

复选框

添加自定义规则
test 可以是正则或者函数

注意:

实现代码:

dynamicValidateForm:{}
domains:[]

复选框如果是一个为逻辑值,如果是多个则绑定到同一个数组:

{
 required: {
  test: /\S+$/,
  message: '必填项'
 }
}

当错误提示信息不按照我们预想的位置显示时,我们可以按照如下方式进行设置自定义错误显示标签放在我们需要显示的位置,当此表单项验证不通过时会将此信息自动显示出来,jquery验证插件会自动帮助我们控制它的显示与隐藏
for=”html元素name值” class=”error”
style=”display:none”>错误信息
如果设置了错误lable标签就不必在messages中设置此表单项错误提示信息了
如果预定义的校验规则尚不能满足需求的话可以进行自定义校验规则:

<script>
// ...
export default {
  data () {
    let validate = (rule, value, callback) => {
      //后台方法
      validateCode(value).then(res => {
        if (res && res.data === 'TRUE') {
          callback()
        } else if (res && res.data === 'FALSE') {
          callback('编码已存在')
        }
      })
    }
    return{
      form:{
        code: ''
      },
      rules:{
        code: [
          { type: 'string', required: true, message: '请您完善此项', trigger: 'blur' }, // 必填校验
          {validator:validate, trigger: 'blur'}
        ],  
      }
  }
}
</script>

要整理成以上的结构(如果一定要这样实现),容易有坑!!

图片 4

组件内注册

自定义校验规则步骤如下:

参考:https://www.npmjs.com/package/async-validator

<el-form-item
    v-for="(domain, index) in dynamicValidateForm.domains"
    :label="'域名' + index"
    :key="domain.key"
    :prop="'domains.' + index + '.value'"
    :rules="{
      required: true, message: '域名不能为空', trigger: 'blur'
    }"
  >
  <!-- 选择框-->
  <el-select filterable v-model="domain.value" placeholder="请选择" >
     <el-option
         v-for="item in domain.options"
         :key="item.value"
         :label="item.label"
         :value="item.value" >
      </el-option>
    </el-select>
  </el-form-item>

<script>
  export default {
     data () {
      dynamicValidateForm:{
        email:'', // 基本属性
        domains:[] // 数组
      }
    },
    created () {
      this.id = this.$route.params.id
      // 有ID,则是编辑页面,否则是新增页面
      if(this.id){
        this.getData()
      }
    },
    methods: {
        getData(){
           getData(this.id).then(res => {
             this.dynamicValidateForm = res.data.dynamicValidateForm 
             this.dynamicValidateForm.domains = res.data.domains
            })
        }
    }
  }
</script>

实例中勾选复选框效果如下所示:

{
 data () {
  username: '',
  password: ''
 },

 vuerify: {
  username: {
   test: /\w{4,}/, // 自定义规则,可以是函数,正则或者全局注册的规则(填字符串)
   message: '至少 4 位字符'
  },
  password: 'required' // 使用全局注册的规则
 }
}

(1)
使用$.validator.addMethod(“校验规则名称”,function(value,element,params)){
return false;//表示校验不通过,会显示错误提示信息}
(2) 在rules中通过校验规则名称使用校验规则
(3) 在messages中定义该规则对应的错误提示信息
其中: value是校验组件的value值
element是校验组件的节点对象
params是校验规则的参数

进入页面后,发现进入编辑页面后,选择框选择后没反应了,页面也没有报错~
为什么呢?
找了半天原因,找了<select>的文档,没发现问题 ~
~~

图片 5

API

//自定义校验规则

$.validator.addMethod("checkUsername", function(value, elem, params) {
  var flag = false;
  $.ajax({
    "url" : "${pageContext.request.contextPath}/checkUsername",
    "data" : {
      "username" : value
    },
    "dataType" : "json",
    "success" : function(data) {
      flag = data.isExist;
    },
    "async" : false//必须用同步,否则flag在被赋值之前就已经return
  });
  return !flag;//返回false表示校验不通过
});

终于,

单选按钮

$vuerify 包含如下属性

但是使用同步请求浏览器发出警告[Deprecation] Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

this.dynamicValidateForm = res.data.dynamicValidateForm this.dynamicValidateForm.domains = res.data.domains

以下实例中演示了单选按钮的双向数据绑定:

name description type default Value
$errors 数据校验失败的错误信息, 例如 username 校验失败会返回 { username:
‘至少 4 位字符’ } Object {}
invalid 存在校验失败的字段 Boolean true
valid 不存在校验失败的字段 Boolean false
check 检查指定字段,传入数组,返回 Boolean Function(Array) –
clear 清空错误列表 Function –

解决方法:使用插件的异步验证

这两行代码,第一行由于res.data.dynamicValidateForm就是一个object,它并没有domains这个属性,赋值后,dynamicValidateForm
中也没有domains这个属性了。而第二行代码,赋值给domains
,没有报错,可是使用的时候,这个属性却不会生效。而<select>绑定的可是domains
中的值。。

图片 6

v-vuerify

remote:URL
使用 ajax
方式进行验证,默认会提交当前验证的值到远程地址,如果需要提交其他的值,可以使用
data 选项。

解决方法:

选中后,效果如下图所示:

该指令可以在表单组件触发 blur 事件时验证数据并为组件设置类名(默认为
.vuerify-invalid)。可以是 input
等原生组件,也可以是自己封装过的组件。提供两个版本

    $(function() {
        $("#myform")
                .validate(
                        {
                            "rules" : {
                                "username" : {
                                    "required" : true,
                                    //"checkUsername" : true
                                    "remote" : {
                                        "type" : "post",
                                        "url" : "${pageContext.request.contextPath}/checkUsername",
                                        "data" : {
                                            "username" : function() {
                                                return $("#username").val();
                                            }
                                        },
                                        //"dataType" : "html",
                                        "dataType" : "json",
                                        "dataFilter" : function(data, type) {
                                            if (type == "json") {
                                                data = JSON.parse(data);
                                                return !data.isExist;
                                            } else {
                                                return data == "true" ? false
                                                        : true;
                                            }
                                        }
                                    }
                                },
                                "password" : {
                                    "required" : true,
                                    "rangelength" : [ 6, 12 ]
                                },
                                "repassword" : {
                                    "required" : true,
                                    "rangelength" : [ 6, 12 ],
                                    "equalTo" : "#password"
                                },
                                "email" : {
                                    "required" : true,
                                    "email" : true
                                },
                                "telephone" : {
                                    "required" : true
                                },
                                "birthday" : {
                                    "required" : true,
                                    "dateISO" : true
                                }
                            },
                            "messages" : {
                                "username" : {
                                    "required" : "用户名不能为空",
                                    //"checkUsername" : "用户名已存在"
                                    "remote" : "用户名已经被注册啦"
                                },
                                "password" : {
                                    "required" : "密码不能为空",
                                    "rangelength" : "密码长度必须介于6到12位"
                                },
                                "repassword" : {
                                    "required" : "密码不能为空",
                                    "rangelength" : "密码长度必须介于6到12位",
                                    "equalTo" : "两次密码输入不一致"
                                },
                                "email" : {
                                    "required" : "邮箱不能为空",
                                    "email" : "邮箱格式不正确"
                                },
                                "telephone" : {
                                    "required" : "电话号码不能为空"
                                },
                                "birthday" : {
                                    "required" : "日期不能为空",
                                    "dateISO" : "日期格式不正确"
                                }
                            }
                        });
    });
this.$set(this.dynamicValidateForm,'domains ',res.data.domains)

图片 7

安装

  • 自定义校验、设置触发方式、ajax刷新验证码图片

在vue.js中,给对象赋值,最好还是使用$set

select 列表

# Vue 1.x
npm v-vuerify -S

# Vue 2.0
npm v-vuerify-next -S

以下实例中演示了下拉列表的双向数据绑定:

用法

<script type="text/javascript">
    //自定义校验规则
    /* $.validator.addMethod("checkUsername", function(value, elem, params) {
        var flag = false;
        $.ajax({
            "url" : "${pageContext.request.contextPath}/checkUsername",
            "data" : {
                "username" : value
            },
            "dataType" : "json",
            "success" : function(data) {
                flag = data.isExist;
            },
            "async" : false
        //必须用同步,否则flag在被赋值之前就已经return
        });
        return !flag;
    }); */

    $(function() {
        $("#randomcode").click(
                function() {
                    $(this).attr(
                            "src",
                            $(this).attr("src")
                                    .substring(
                                            0,
                                            $(this).attr("src").indexOf(
                                                    "randomcode") + 10)
                                    + "&" + new Date().getTime())
                });

        $("#myform")
                .validate(
                        {   //"debug" : true,
                            "onkeyup":function(){
                                //alert("什么也不做~~");
                            },
                            "rules" : {
                                "username" : {
                                    "required" : true,
                                    //"checkUsername" : true
                                    "remote" : {
                                        "type" : "post",
                                        "url" : "${pageContext.request.contextPath}/user?method=checkUsername",
                                        "data" : {
                                            "username" : function() {
                                                return $("#username").val();
                                            }
                                        },
                                        "dataType" : "json",
                                        "dataFilter" : function(data, type) {
                                            //alert(type);//json
                                            if (type == "json") {
                                                data = JSON.parse(data);
                                                return !data.isExist;
                                            } else {
                                                return data == "true" ? false
                                                        : true;
                                            }
                                        }
                                    }
                                },
                                "password" : {
                                    "required" : true,
                                    "rangelength" : [ 6, 12 ]
                                },
                                "repassword" : {
                                    "required" : true,
                                    "rangelength" : [ 6, 12 ],
                                    "equalTo" : "#password"
                                },
                                "email" : {
                                    "required" : true,
                                    "email" : true
                                },
                                "telephone" : {
                                    "required" : true
                                },
                                "birthday" : {
                                    "required" : true,
                                    "dateISO" : true
                                },
                                "randomcode" : {
                                    "required" : true,
                                    "remote" : {
                                        "type" : "post",
                                        "url" : "${pageContext.request.contextPath}/user?method=checkRandomcode",
                                        "data" : {
                                            "username" : function() {
                                                return $("#randomcode").val();
                                            }
                                        },
                                        "dataType" : "html",
                                        "dataFilter" : function(data, type) {
                                            //alert(type);//json
                                            if (type == "json") {
                                                data = JSON.parse(data);
                                                return !data.isExist;
                                            } else {
                                                if(data=="false"){
                                                    /* alert("失败>刷新") */
                                                    $("#randomcode").attr(
                                                            "src",
                                                            $("#randomcode").attr("src")
                                                                    .substring(
                                                                            0,
                                                                            $("#randomcode").attr("src").indexOf(
                                                                                    "randomcode") + 10)
                                                                    + "&" + new Date().getTime());

                                                }
                                                return data == "true" ? true
                                                        : false;
                                            }
                                        }
                                    }
                                }
                            },
                            "messages" : {
                                "username" : {
                                    "required" : "用户名不能为空",
                                    //"checkUsername" : "用户名已存在"
                                    "remote" : "用户名已经被注册啦"
                                },
                                "password" : {
                                    "required" : "密码不能为空",
                                    "rangelength" : "密码长度必须介于6到12位"
                                },
                                "repassword" : {
                                    "required" : "密码不能为空",
                                    "rangelength" : "密码长度必须介于6到12位",
                                    "equalTo" : "两次密码输入不一致"
                                },
                                "email" : {
                                    "required" : "邮箱不能为空",
                                    "email" : "邮箱格式不正确"
                                },
                                "telephone" : {
                                    "required" : "电话号码不能为空"
                                },
                                "birthday" : {
                                    "required" : "日期不能为空",
                                    "dateISO" : "日期格式不正确"
                                },
                                "randomcode" : {
                                    "required" : "验证码不能为空",
                                    "remote" : "验证码错误"
                                }
                            }
                        });
    });
</script>

图片 8

import Vue from 'vue'
import VuerifyDirective from 'v-vuerify' // Vue1.x
import VuerifyDirective from 'v-vuerify-next' // Vue2.0

Vue.use(VuerifyDirective)
<input v-model="username" v-vuerify="'username'">

<x-input :value.sync="password" v-vuerify="'password'"></x-input>

选取 Runoob,输出效果如下所示:

Params

图片 9

verifyInvalidClass


默认类名为 vuerify-invalid

修饰符

<input v-model=”username” v-vuerify=”‘username'”
vuerify-invalid-class=”error”>

.lazy

Modifiers

在默认情况下, v-model 在 input
事件中同步输入框的值与数据,但你可以添加一个修饰符 lazy ,从而转变为在
change 事件中同步:

parent
如果 vuerify 是在父组件注册的,那么就需要指定
parent,让指令可以从父组件获取对应的 $vuerify,具体看 demo

图片 10

Events

.number

vuerify-invalid
vuerify-valid

如果想自动将用户的输入值转为 Number 类型(如果原值的转换结果为 NaN
则返回原值),可以添加一个修饰符 number 给 v-model 来处理输入值:

Github:

图片 11

您可能感兴趣的文章:

  • Vue2.0表单校验组件vee-validate的使用详解
  • VeeValidate在vue项目里表单校验应用案例

这通常很有用,因为在 type=”number” 时 HTML
中输入的值也总是会返回字符串类型。

.trim

如果要自动过滤用户输入的首尾空格,可以添加 trim 修饰符到 v-model
上过滤输入:

图片 12


内容来自:runoob.com 菜鸟教程

整理:极动云,宁波家电物联网云平台

CONTACT US:

相关文章