表单验证

何为表单验证呢?

百度百科给出的回答是这样的:

表单验证是javascript中的高级选项之一。JavaScript 可用来在数据被送往服务器前对 HTML 表单中的这些输入数据进行验证 [1]  。
被 JavaScript 验证的这些典型的表单数据有:
用户是否已填写表单中的必填项目?
用户输入的邮件地址是否合法?
用户是否已输入合法的日期?
用户是否在数据域(numeric field) 中输入了文本?

用大白话说 可以举例类似 ,我们在一个网站的注册页面,填写一些相关信息,这时候 点击提交的时候,如果我们有些“必填”信息没有输入,网站就会给出相应的提示,比如:密码不能为空,已填入信息的正确性、身份证格式、手机格式错误等等。此类验证我们都统称为表单验证,那我们今天看看 在小程序中,我们如何可以更方便的处理类似的表单验证呢?

我们以注册场景为例,看看 本篇内容要实现什么效果:

以上就是我们实现后的表单验证效果。那我们一起来是如何实现的吧~

代码实现

插件介绍

首先我们需要用到一个 WxValidate - 表单验证的js插件。我们一起来看看它里面包含什么内容:

在小程序中使用

 看了上面的插件介绍,是不是还是一头雾水呢?不要急,下面,我们就来一起看看上面的验证效果配合插件是如何实现的吧。
①,我们需要引入WxValidate.js,可以直接复制如下js代码块:
 /**
* 表单验证
*
* @param {Object} rules 验证字段的规则
* @param {Object} messages 验证字段的提示信息
*
*/
class WxValidate {
constructor(rules = {}, messages = {}) {
Object.assign(this, {
data: {},
rules,
messages,
})
this.__init()
} /**
* __init
*/
__init() {
this.__initMethods()
this.__initDefaults()
this.__initData()
} /**
* 初始化数据
*/
__initData() {
this.form = {}
this.errorList = []
} /**
* 初始化默认提示信息
*/
__initDefaults() {
this.defaults = {
messages: {
required: '这是必填字段。',
email: '请输入有效的电子邮件地址。',
tel: '请输入11位的手机号码。',
url: '请输入有效的网址。',
date: '请输入有效的日期。',
dateISO: '请输入有效的日期(ISO),例如:2009-06-23,1998/01/22。',
number: '请输入有效的数字。',
digits: '只能输入数字。',
idcard: '请输入18位的有效身份证。',
equalTo: this.formatTpl('输入值必须和 {0} 相同。'),
contains: this.formatTpl('输入值必须包含 {0}。'),
minlength: this.formatTpl('最少要输入 {0} 个字符。'),
maxlength: this.formatTpl('最多可以输入 {0} 个字符。'),
rangelength: this.formatTpl('请输入长度在 {0} 到 {1} 之间的字符。'),
min: this.formatTpl('请输入不小于 {0} 的数值。'),
max: this.formatTpl('请输入不大于 {0} 的数值。'),
range: this.formatTpl('请输入范围在 {0} 到 {1} 之间的数值。'),
}
}
} /**
* 初始化默认验证方法
*/
__initMethods() {
const that = this
that.methods = {
/**
* 验证必填元素
*/
required(value, param) {
if (!that.depend(param)) {
return 'dependency-mismatch'
} else if (typeof value === 'number') {
value = value.toString()
} else if (typeof value === 'boolean') {
return !0
} return value.length > 0
},
/**
* 验证电子邮箱格式
*/
email(value) {
return that.optional(value) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(value)
},
/**
* 验证手机格式
*/
tel(value) {
return that.optional(value) || /^1[34578]\d{9}$/.test(value)
},
/**
* 验证URL格式
*/
url(value) {
return that.optional(value) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value)
},
/**
* 验证日期格式
*/
date(value) {
return that.optional(value) || !/Invalid|NaN/.test(new Date(value).toString())
},
/**
* 验证ISO类型的日期格式
*/
dateISO(value) {
return that.optional(value) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(value)
},
/**
* 验证十进制数字
*/
number(value) {
return that.optional(value) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value)
},
/**
* 验证整数
*/
digits(value) {
return that.optional(value) || /^\d+$/.test(value)
},
/**
* 验证身份证号码
*/
idcard(value) {
return that.optional(value) || /^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}([0-9]|X)$/.test(value)
},
/**
* 验证两个输入框的内容是否相同
*/
equalTo(value, param) {
return that.optional(value) || value === that.data[param]
},
/**
* 验证是否包含某个值
*/
contains(value, param) {
return that.optional(value) || value.indexOf(param) >= 0
},
/**
* 验证最小长度
*/
minlength(value, param) {
return that.optional(value) || value.length >= param
},
/**
* 验证最大长度
*/
maxlength(value, param) {
return that.optional(value) || value.length <= param
},
/**
* 验证一个长度范围[min, max]
*/
rangelength(value, param) {
return that.optional(value) || (value.length >= param[0] && value.length <= param[1])
},
/**
* 验证最小值
*/
min(value, param) {
return that.optional(value) || value >= param
},
/**
* 验证最大值
*/
max(value, param) {
return that.optional(value) || value <= param
},
/**
* 验证一个值范围[min, max]
*/
range(value, param) {
return that.optional(value) || (value >= param[0] && value <= param[1])
},
}
} /**
* 添加自定义验证方法
* @param {String} name 方法名
* @param {Function} method 函数体,接收两个参数(value, param),value表示元素的值,param表示参数
* @param {String} message 提示信息
*/
addMethod(name, method, message) {
this.methods[name] = method
this.defaults.messages[name] = message !== undefined ? message : this.defaults.messages[name]
} /**
* 判断验证方法是否存在
*/
isValidMethod(value) {
let methods = []
for (let method in this.methods) {
if (method && typeof this.methods[method] === 'function') {
methods.push(method)
}
}
return methods.indexOf(value) !== -1
} /**
* 格式化提示信息模板
*/
formatTpl(source, params) {
const that = this
if (arguments.length === 1) {
return function() {
let args = Array.from(arguments)
args.unshift(source)
return that.formatTpl.apply(this, args)
}
}
if (params === undefined) {
return source
}
if (arguments.length > 2 && params.constructor !== Array) {
params = Array.from(arguments).slice(1)
}
if (params.constructor !== Array) {
params = [params]
}
params.forEach(function(n, i) {
source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function() {
return n
})
})
return source
} /**
* 判断规则依赖是否存在
*/
depend(param) {
switch (typeof param) {
case 'boolean':
param = param
break
case 'string':
param = !!param.length
break
case 'function':
param = param()
default:
param = !0
}
return param
} /**
* 判断输入值是否为空
*/
optional(value) {
return !this.methods.required(value) && 'dependency-mismatch'
} /**
* 获取自定义字段的提示信息
* @param {String} param 字段名
* @param {Object} rule 规则
*/
customMessage(param, rule) {
const params = this.messages[param]
const isObject = typeof params === 'object'
if (params && isObject) return params[rule.method]
} /**
* 获取某个指定字段的提示信息
* @param {String} param 字段名
* @param {Object} rule 规则
*/
defaultMessage(param, rule) {
let message = this.customMessage(param, rule) || this.defaults.messages[rule.method]
let type = typeof message if (type === 'undefined') {
message = `Warning: No message defined for ${rule.method}.`
} else if (type === 'function') {
message = message.call(this, rule.parameters)
} return message
} /**
* 缓存错误信息
* @param {String} param 字段名
* @param {Object} rule 规则
* @param {String} value 元素的值
*/
formatTplAndAdd(param, rule, value) {
let msg = this.defaultMessage(param, rule) this.errorList.push({
param: param,
msg: msg,
value: value,
})
} /**
* 验证某个指定字段的规则
* @param {String} param 字段名
* @param {Object} rules 规则
* @param {Object} data 需要验证的数据对象
*/
checkParam(param, rules, data) { // 缓存数据对象
this.data = data // 缓存字段对应的值
const value = data[param] !== null && data[param] !== undefined ? data[param] : '' // 遍历某个指定字段的所有规则,依次验证规则,否则缓存错误信息
for (let method in rules) { // 判断验证方法是否存在
if (this.isValidMethod(method)) { // 缓存规则的属性及值
const rule = {
method: method,
parameters: rules[method]
} // 调用验证方法
const result = this.methods[method](value, rule.parameters) // 若result返回值为dependency-mismatch,则说明该字段的值为空或非必填字段
if (result === 'dependency-mismatch') {
continue
} this.setValue(param, method, result, value) // 判断是否通过验证,否则缓存错误信息,跳出循环
if (!result) {
this.formatTplAndAdd(param, rule, value)
break
}
}
}
} /**
* 设置字段的默认验证值
* @param {String} param 字段名
*/
setView(param) {
this.form[param] = {
$name: param,
$valid: true,
$invalid: false,
$error: {},
$success: {},
$viewValue: ``,
}
} /**
* 设置字段的验证值
* @param {String} param 字段名
* @param {String} method 字段的方法
* @param {Boolean} result 是否通过验证
* @param {String} value 字段的值
*/
setValue(param, method, result, value) {
const params = this.form[param]
params.$valid = result
params.$invalid = !result
params.$error[method] = !result
params.$success[method] = result
params.$viewValue = value
} /**
* 验证所有字段的规则,返回验证是否通过
* @param {Object} data 需要验证数据对象
*/
checkForm(data) {
this.__initData() for (let param in this.rules) {
this.setView(param)
this.checkParam(param, this.rules[param], data)
} return this.valid()
} /**
* 返回验证是否通过
*/
valid() {
return this.size() === 0
} /**
* 返回错误信息的个数
*/
size() {
return this.errorList.length
} /**
* 返回所有错误信息
*/
validationErrors() {
return this.errorList
}
} export default WxValidate

②在我们要验证的页面js中导入js,并在data中增加form子元素

//导入验证js
import WxValidate from "../../utils/WxValidate"; data: {
form: {//增加form子元素
items: [
{ name: '1', value: '男', checked: 'true' },
{ name: '2', value: '女' }
],
date: '请选择出生年月',
casArray: ['身份证', '护照', '其他/港澳台居民身份证', '外国人永久居留身份证'],
}
},

③初始化表单验证规则,我一般写在onLoad中

onLoad: function () {
this.initValidate();
},
initValidate() {
let rules = {
Name: {
required: true,
maxlength: 10
},
sex: {
required: true,
number: true
}
,
birthDate: {
required: true,
dateISO: true,
},
Card: {
required: false,
idcard: true
}
} let message = {
Name: {
required: '请输入姓名',
maxlength: '名字不能超过10个字'
},
Card: {
idcard: "请输入正确的身份证号码"
},
sex: {
required: "请选择您的性别",
number: '请您选择您的性别'
}
,
birthDate: {
required: "请选择出生年月",
dateISO: "请选择出生年月",
},
}
//实例化当前的验证规则和提示消息
this.WxValidate = new WxValidate(rules, message);
}

④最后在表单提交方法中调用验证方法就行了

formSubmit: function (e) {
let params = e.detail.value;
if (!this.WxValidate.checkForm(params)) {
//表单元素验证不通过,此处给出相应提示
let error = this.WxValidate.errorList[0];
switch (error.param) {
case "Name":
//TODO
break;
case "sex":
//TODO
break;
case "birthDate":
//TODO
break;
case "Card":
//TODO
break; }
}
return false;
}
//验证通过,往下执行

End

微信小程序之表单验证的更多相关文章

  1. 微信小程序-form表单-获取用户输入文本框的值

    微信小程序-form表单-获取用户输入文本框的值 <input name='formnickname' class="textarea" placeholder=" ...

  2. 微信小程序_(表单组件)checkbox与label

    微信小程序组件checkbox官方文档 传送门 微信小程序组件label官方文档 传送门 Learn 一.checkbox组件 二.label组件与checkbox组件共用 一.checkbox组件 ...

  3. 微信小程序_(表单组件)button组件的使用

    微信小程序表单组件button官方文档 传送门 Learn 一.button组件的使用 一.button组件的使用 size:按钮的大小[默认值default] type:按钮的样式类型[默认值def ...

  4. 微信小程序之表单提交

    页面绑定很多事件! <view class="content"> <view class="user personal_func_list"& ...

  5. 微信小程序常用表单校验方法(手机号校验、身份证号(严格和非严格校验、验证码六位数字校验))

    util.js function isPhone(value) { if (!/^1(3|4|5|7|8)\d{9}$/.test(value)) { return false } else { re ...

  6. 2017-01-11小程序form表单提交

    小程序form表单提交 1.小程序相对于之前的WEB+PHP建站来说,个人理解为只是将web放到了微信端,用小程序固定的格式前前端进行布局.事件触发和数据的输送和读取,服务器端可以用任何后端语言写,但 ...

  7. 原创:经验分享:微信小程序外包接单常见问题及流程

    从九月底内测到现在已经三个半月.凌晨一点睡觉已经习以为常,也正是这样,才让无前端经验的我做微信小程序开发并不感到费劲.最近才开始接微信小程序的外包项目,目前已经签下了五份合同,成品出了两个.加上转给朋 ...

  8. [转]经验分享:微信小程序外包接单常见问题及流程

    本文转自:https://www.cnblogs.com/wxapp-union/p/6245301.html 从九月底内测到现在已经三个半月.凌晨一点睡觉已经习以为常,也正是这样,才让无前端经验的我 ...

  9. 微信小程序 TOP100 榜单

    8 月 12 日,阿拉丁数据统计平台发布了国内第一份小程序 TOP100 榜单,摩拜单车成为全榜第一! 该榜单数据来源于阿拉丁小程序统计平台检测.合作.如有赞等,并经过企业电话调研和实地走访企业等校准 ...

随机推荐

  1. Python3实现ICMP远控后门(上)_补充篇

    ICMP后门(上)补充篇 前言 在上一篇文章Python3实现ICMP远控后门(上)中,我简要讲解了ICMP协议,以及实现了一个简单的ping功能,在文章发表之后,后台很多朋友留言,说对校验和的计算不 ...

  2. Python并发编程之创建多线程的几种方法(二)

    大家好,并发编程 进入第二篇. 今天的内容会比较基础,主要是为了让新手也能无障碍地阅读,所以还是要再巩固下基础.学完了基础,你们也就能很顺畅地跟着我的思路理解以后的文章. 本文目录 学会使用函数创建多 ...

  3. Docker容器发布spring boot项目

    一.安装Docker环境 yum install docker 安装完成后,使用下面的命令来启动 docker 服务,并将其设置为开机启动: systemctl start docker.servic ...

  4. linux常用的时间获取函数(time,gettimeofday,clock_gettime,_ftime,localtime,strftime )

    time()提供了秒级的精确度 1.头文件 <time.h> 2.函数原型 time_t time(time_t * timer) 函数返回从TC1970-1-1 0:0:0开始到现在的秒 ...

  5. Git Submodule简单操作

    基于组件的项目很多,但是如果直接用包的方式直接引用到项目中,如果出现问题很难进行调试的操作,也很难进行组件的优化和管理,所以写了一篇文章来介绍下git submodule的用法,用submodule可 ...

  6. 传统IT公司/创业公司/互联网大公司的offer如何选择?[转载+原创]

    背景介绍: 第一家工作的公司是一家跨国外企安全公司, 骄傲的称自己不是互联网公司而是传统软件公司, 第二家公司是当下最热的知识分享社区, 创业公司. 第三家公司是挤走谷歌, 曾一度称霸中国的搜索引擎公 ...

  7. Spring Boot 使用 AOP 实现页面自适应

    鉴于复杂页面自适应的难度,一般会做几套模板分别适应手机.平板.电脑等设备.使用 Spring Boot 开发单体应用时,一般会使用 Thymeleaf 模板,那么可以使用 AOP 技术来实现页面自适应 ...

  8. LeetCode Javascript实现 344. Reverse String 292. Nim Game 371. Sum of Two Integers

    344. Reverse String /** * @param {string} s * @return {string} */ var reverseString = function(s) { ...

  9. 7-25 :active :after :before :disabled

    1:<list,<datalist>,required,<select>,<option>,title,draggable,hidden 2:data-*和命 ...

  10. Java 开发, volatile 你必须了解一下

    上一篇文章说了 CAS 原理,其中说到了 Atomic* 类,他们实现原子操作的机制就依靠了 volatile 的内存可见性特性.如果还不了解 CAS 和 Atomic*,建议看一下我们说的 CAS ...