├── input ├── input.json ├── data.js ├── input.wxss ├── input.wxml ├── properties.js ├── input.js └── validate.js └── README.md /input/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "component":true 3 | } -------------------------------------------------------------------------------- /input/data.js: -------------------------------------------------------------------------------- 1 | export default { 2 | value: '', 3 | error:false 4 | } -------------------------------------------------------------------------------- /input/input.wxss: -------------------------------------------------------------------------------- 1 | /* valid input css */ 2 | 3 | .flex{ 4 | display:flex; 5 | align-items: center; 6 | } 7 | .flex-center{ 8 | justify-content: center; 9 | } 10 | .flex-start{ 11 | justify-content: flex-start; 12 | } 13 | .flex-between{ 14 | justify-content: space-between; 15 | } 16 | .flex-around{ 17 | justify-content: space-around; 18 | } 19 | 20 | .valid_input_content{ 21 | width:100%; 22 | padding:4px 24rpx; 23 | box-sizing: border-box; 24 | font-size: 24rpx; 25 | } 26 | 27 | .valid_input{ 28 | width:80%; 29 | height: 65rpx; 30 | transition: border .3s linear,box-shadow .3s linear; 31 | } 32 | 33 | .valid_error_tip{ 34 | box-shadow: 0px 0px 3px 1px red; 35 | } -------------------------------------------------------------------------------- /input/input.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /input/properties.js: -------------------------------------------------------------------------------- 1 | export default { 2 | flex:{ // 弹性布局方式 3 | type:String, 4 | value:'flex-start' 5 | }, 6 | placeHolder:{ 7 | type:String, // 提示语 8 | value:'请输入您的数据' 9 | }, 10 | validType:{ 11 | type:String, // 验证类型 12 | value:'' 13 | }, 14 | type:{ // 输入框类型 15 | type:String, 16 | value:'text' 17 | }, 18 | validTime:{ 19 | type:String, 20 | value: 'blur' 21 | }, 22 | validToast:{ // 验证错误提示 23 | type:String, 24 | value:'' 25 | }, 26 | initValue:{ // 初始值 27 | type:String, 28 | value:'' 29 | }, 30 | maxLength:{ // 最大长度 31 | type:Number, 32 | value:140 33 | }, 34 | adjustPosition:{ // 是否上推页面 35 | type:Boolean, 36 | value:true 37 | }, 38 | confirmType:{ // 确认按钮类型 39 | type:String, 40 | value: 'done' 41 | }, 42 | focus:{ // 是否自动聚焦 43 | type:Boolean, 44 | value:false 45 | }, 46 | placeholderClass:{ // 提示信息样式 47 | type:String, 48 | value:'input-placeholder' 49 | }, 50 | errorBorder:{ // 验证错误时是否进行border边框展示(红色) 51 | type:Boolean, 52 | value:true 53 | }, 54 | password:{ // 是否为密码类型 55 | type:Boolean, 56 | value:false 57 | }, 58 | disabled:{ // 是否禁用 59 | type:Boolean, 60 | value:false 61 | }, 62 | name:{ // 作为表单提交时获取name 63 | type:String, 64 | value:'' 65 | } 66 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wx-validInput 2 | 微信小程序校验输入框组件 3 | 4 | ## 主要使用方法 5 | > 将validInput组件下载下来,在要使用的页面的json文件中加入下面代码 6 | 7 | ```json 8 | "usingComponents": { 9 | "validInput": "/你的路径/input/input" 10 | } 11 | ``` 12 | 13 | > 在对应的wxml页面 14 | 15 | ```html 16 | 28 | 29 | ``` 30 | 31 | ## 校验类型 32 | | 校验类型 | 参数名 | 33 | |:-------:|:-------:| 34 | | 姓名 | name | 35 | | 手机号 | tel | 36 | | 银行卡号 | bankCard | 37 | | 身份证号 | idCard | 38 | | QQ | QQ | 39 | | 日期 | date | 40 | | email | email | 41 | | 邮编 | ecode | 42 | 43 | 44 | ## props(这里只列出和input组件中不同的参数,其余未提出的input属性可直接使用) 45 | | props | 参数名 | 参数类型 | 默认值 | 46 | |:-------:|:-------:|:-------:|:-------:| 47 | | 提示信息 | place-holder | String | 请输入您的数据 | 48 | | 验证类型 | valid-type | String | | 49 | | 验证时机 | valid-time | String | blur | 50 | | 验证错误提示 | valid-toast | String | | 51 | | 初始值 | init-value | String | | 52 | | 最大长度 | max-length | Number | 140 | 53 | | 错误红色阴影提示 | error-border | Boolean | true | 54 | 55 | -------------------------------------------------------------------------------- /input/input.js: -------------------------------------------------------------------------------- 1 | let properties = require('./properties').default; 2 | let data = require('./data').default; 3 | let validate = require('./validate').default; 4 | 5 | Component({ 6 | behaviors: ['wx://form-field'], // 获取form表单提交能力 7 | options: { 8 | multipleSlots: true 9 | }, 10 | properties, 11 | data, 12 | // 当组件节点准备好时,进行初始vendor 13 | ready(){ 14 | let { initValue } = this.data; 15 | initValue ? this.setData({value:initValue}) : void(0); 16 | }, 17 | methods: { 18 | checkFunction(handler){ 19 | return Object.prototype.toString.call(handler) == "[Object,Object]"; 20 | }, 21 | input(event){ 22 | let { value } = event.detail; 23 | this.change(event); 24 | this.triggerEvent('input', event, event); 25 | this.setData({value:validate.trims(value,'g')}) 26 | this.timeToValid('input',event); 27 | 28 | }, 29 | focus(event){ 30 | this.triggerEvent('focus', event, event); 31 | this.timeToValid('focus',event); 32 | }, 33 | change(event){ 34 | this.triggerEvent('change', event, event); 35 | this.timeToValid('change',event); 36 | }, 37 | blur(event){ 38 | let { detail:{ value } } = event; 39 | this.setData({value}) 40 | this.triggerEvent('blur', event, event); 41 | this.timeToValid('blur',event); 42 | }, 43 | confirm(event){ 44 | this.triggerEvent('confirm', event, event); 45 | this.timeToValid('confirm',event); 46 | }, 47 | submit(event){ 48 | console.log(11111) 49 | }, 50 | // 校验函数 51 | valid(event){ 52 | let { type , detail , currentTarget} = event; 53 | 54 | // 解析value和自定义验证时间进行相应验证类型的验证 55 | let { value } = detail, 56 | /* 这里解释一下为什么不从this.data上结构value,因为在输入过程中value并不会双向响应 */ 57 | { validtype, validtoast } = currentTarget.dataset; 58 | /* 59 | * 验证过程逻辑分析 60 | * 1. 是否存在验证事件类型 61 | * 2. 是否存在验证类型 62 | * 3. 是否存在value 63 | * 4. 是否toast提示 64 | */ 65 | var validEventArray = ['input','change','blur']; 66 | if(validEventArray.includes(type) && validate.hasOwnProperty(validtype)){ 67 | console.log(this.data) 68 | var reg = validate[validtype]; 69 | if(!reg(value)){ 70 | this.showToast(validtype,validtoast); 71 | }else{ 72 | this.setData({error: false}) 73 | } 74 | } 75 | }, 76 | showToast(validtype,validtoast=''){ 77 | /* 这里需要整合提示,如果你每次都输入提示的话可以将此处的对象删除 */ 78 | let prefix = '您输入的', 79 | endfix = '格式不正确'; 80 | let toastmsg = { 81 | 'tel': '手机号', 82 | 'bankCard': '银行卡号', 83 | 'idCard': '身份证号', 84 | 'phone': '座机号码', 85 | 'date' : '时间', 86 | 'email': '邮箱地址', 87 | 'QQ': 'QQ', 88 | 'name': '姓名', 89 | 'ecode': '邮编' 90 | }; 91 | validtoast = validtoast ? validtoast : `${prefix}${toastmsg[validtype]}${endfix}`; 92 | let { errorBorder } = this.data; 93 | if(errorBorder){this.setData({error: true});} 94 | wx.showToast({mask:true,title:validtoast,icon:'none'}) 95 | }, 96 | /* 启用那个函数进行错误处理 */ 97 | timeToValid(type,event){ 98 | let {validTime} = this.data; 99 | type == validTime ? this.valid(event) : void(0); 100 | 101 | } 102 | }, 103 | externalClasses:['valid_input_selfclass'] 104 | }) -------------------------------------------------------------------------------- /input/validate.js: -------------------------------------------------------------------------------- 1 | /* 去除所有空格 */ 2 | function trimAll(value,all=''){ 3 | var result; 4 | result = value.replace(/(^\s+)|(\s+$)/g,""); 5 | if(all.toLowerCase()=="g")result = value.replace(/\s/g,""); 6 | return result; 7 | } 8 | 9 | /* 验证手机号 */ 10 | function phone_check(pp){ 11 | if((/^[1][0123456789]+\d{9}$/.test(pp)) && pp.length == 11 && pp.slice(0, 1) == 1){ 12 | return true; 13 | } 14 | return false; 15 | } 16 | 17 | /*验证银行卡号码*/ 18 | var checkUcredit = function (no) { 19 | if (no.length < 16 || no.length > 19) { 20 | //$("#noInfo").html("银行卡号长度必须在16到19之间"); 21 | return false; 22 | } 23 | var num = /^\d*$/; //全数字 24 | if (!num.exec(no)) { 25 | //$("#noInfo").html("银行卡号必须全为数字"); 26 | return false; 27 | } 28 | //开头6位 29 | var strBin = "10,18,30,35,37,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,58,60,62,65,68,69,84,87,88,94,95,98,99"; 30 | if (strBin.indexOf(no.substring(0, 2)) == -1) {//银行卡号开头6位不符合规范 31 | return false; 32 | } 33 | var lastNum = no.substr(no.length - 1, 1); //取出最后一位(与luhm进行比较) 34 | 35 | var first15Num = no.substr(0, no.length - 1); //前15或18位 36 | var newArr = new Array(); 37 | for (var i = first15Num.length - 1; i > -1; i--) { //前15或18位倒序存进数组 38 | newArr.push(first15Num.substr(i, 1)); 39 | } 40 | var arrJiShu = new Array(); //奇数位*2的积 <9 41 | var arrJiShu2 = new Array(); //奇数位*2的积 >9 42 | 43 | var arrOuShu = new Array(); //偶数位数组 44 | for (var j = 0; j < newArr.length; j++) { 45 | if ((j + 1) % 2 == 1) { //奇数位 46 | if (parseInt(newArr[j]) * 2 < 9) 47 | arrJiShu.push(parseInt(newArr[j]) * 2); 48 | else 49 | arrJiShu2.push(parseInt(newArr[j]) * 2); 50 | } else //偶数位 51 | arrOuShu.push(newArr[j]); 52 | } 53 | 54 | var jishu_child1 = new Array(); //奇数位*2 >9 的分割之后的数组个位数 55 | var jishu_child2 = new Array(); //奇数位*2 >9 的分割之后的数组十位数 56 | for (var h = 0; h < arrJiShu2.length; h++) { 57 | jishu_child1.push(parseInt(arrJiShu2[h]) % 10); 58 | jishu_child2.push(parseInt(arrJiShu2[h]) / 10); 59 | } 60 | 61 | var sumJiShu = 0; //奇数位*2 < 9 的数组之和 62 | var sumOuShu = 0; //偶数位数组之和 63 | var sumJiShuChild1 = 0; //奇数位*2 >9 的分割之后的数组个位数之和 64 | var sumJiShuChild2 = 0; //奇数位*2 >9 的分割之后的数组十位数之和 65 | var sumTotal = 0; 66 | for (var m = 0; m < arrJiShu.length; m++) { 67 | sumJiShu = sumJiShu + parseInt(arrJiShu[m]); 68 | } 69 | 70 | for (var n = 0; n < arrOuShu.length; n++) { 71 | sumOuShu = sumOuShu + parseInt(arrOuShu[n]); 72 | } 73 | 74 | for (var p = 0; p < jishu_child1.length; p++) { 75 | sumJiShuChild1 = sumJiShuChild1 + parseInt(jishu_child1[p]); 76 | sumJiShuChild2 = sumJiShuChild2 + parseInt(jishu_child2[p]); 77 | } 78 | //计算总和 79 | sumTotal = parseInt(sumJiShu) + parseInt(sumOuShu) + parseInt(sumJiShuChild1) + parseInt(sumJiShuChild2); 80 | 81 | //计算Luhm值 82 | var k = parseInt(sumTotal) % 10 == 0 ? 10 : parseInt(sumTotal) % 10; 83 | var luhm = 10 - k; 84 | 85 | if (lastNum == luhm) { 86 | return true; 87 | } else { 88 | return false; 89 | } 90 | } 91 | 92 | /* start 身份证号码 */ 93 | var Wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1]; // 加权因子 94 | var ValideCode = [1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2]; // 身份证验证位值.10代表X 95 | function IdCardValidate(idCard) { 96 | idCard = trim(idCard.replace(/ /g, "")); //去掉字符串头尾空格 97 | if (idCard.length == 15) { 98 | return isValidityBrithBy15IdCard(idCard); //进行15位身份证的验证 99 | } else if (idCard.length == 18) { 100 | var a_idCard = idCard.split(""); // 得到身份证数组 101 | if (isValidityBrithBy18IdCard(idCard) && isTrueValidateCodeBy18IdCard(a_idCard)) { //进行18位身份证的基本验证和第18位的验证 102 | return true; 103 | } else { 104 | return false; 105 | } 106 | } else { 107 | return false; 108 | } 109 | } 110 | 111 | /** 112 | * 判断身份证号码为18位时最后的验证位是否正确 113 | * @param a_idCard 身份证号码数组 114 | * @return 115 | */ 116 | function isTrueValidateCodeBy18IdCard(a_idCard) { 117 | var sum = 0; // 声明加权求和变量 118 | if (a_idCard[17].toLowerCase() == 'x') { 119 | a_idCard[17] = 10; // 将最后位为x的验证码替换为10方便后续操作 120 | } 121 | for (var i = 0; i < 17; i++) { 122 | sum += Wi[i] * a_idCard[i]; // 加权求和 123 | } 124 | var valCodePosition = sum % 11; // 得到验证码所位置 125 | if (a_idCard[17] == ValideCode[valCodePosition]) { 126 | return true; 127 | } else { 128 | return false; 129 | } 130 | } 131 | 132 | /** 133 | * 验证18位数身份证号码中的生日是否是有效生日 134 | * @param idCard 18位书身份证字符串 135 | * @return 136 | */ 137 | function isValidityBrithBy18IdCard(idCard18) { 138 | var year = idCard18.substring(6, 10); 139 | var month = idCard18.substring(10, 12); 140 | var day = idCard18.substring(12, 14); 141 | var temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day)); 142 | // 这里用getFullYear()获取年份,避免千年虫问题 143 | if (temp_date.getFullYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 || temp_date.getDate() != parseFloat(day)) { 144 | return false; 145 | } else { 146 | return true; 147 | } 148 | } 149 | 150 | /** 151 | * 验证15位数身份证号码中的生日是否是有效生日 152 | * @param idCard15 15位书身份证字符串 153 | * @return 154 | */ 155 | function isValidityBrithBy15IdCard(idCard15) { 156 | var year = idCard15.substring(6, 8); 157 | var month = idCard15.substring(8, 10); 158 | var day = idCard15.substring(10, 12); 159 | var temp_date = new Date(year, parseFloat(month) - 1, parseFloat(day)); 160 | // 对于老身份证中的你年龄则不需考虑千年虫问题而使用getYear()方法 161 | if (temp_date.getYear() != parseFloat(year) || temp_date.getMonth() != parseFloat(month) - 1 || temp_date.getDate() != parseFloat(day)) { 162 | return false; 163 | } else { 164 | return true; 165 | } 166 | } 167 | 168 | //去掉字符串头尾空格 169 | function trim(str) { 170 | return str.replace(/(^\s*)|(\s*$)/g, ""); 171 | } 172 | /*end 身份证*/ 173 | 174 | /* 验证电话号(座机) */ 175 | function checktel(tel){ 176 | return /\d{3}-\d{8}|\d{4}-\d{7}/.test(tel); 177 | /* eg: 021-87888822 */ 178 | } 179 | 180 | /* 验证日期格式 */ 181 | function checkDate(date){ 182 | return /^\d{4}-\d{1,2}-\d{1,2}/.test(date); 183 | /* eg: 2018-04-28 */ 184 | } 185 | 186 | /* email地址 */ 187 | function checkEmail(email){ 188 | return /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(email); 189 | /* eg:www.wangyi@163.com || wangyi@163.com */ 190 | } 191 | 192 | /* QQ号码 */ 193 | function checkQQ(qq){ 194 | return /[1-9][0-9]{4,}/.test(qq); // 从10000开始 195 | } 196 | 197 | /* 邮政编码 */ 198 | function checkECode(ecode){ 199 | return /[1-9]\d{5}(?!\d)/.test(ecode); 200 | } 201 | 202 | /* 姓名 */ 203 | function checkName(name){ 204 | return /^[\u4e00-\u9fa5]{2,6}$/.test(name); // 国家规定名字需要为两个以上,六个以下 205 | } 206 | 207 | /* */ 208 | 209 | export default 210 | { 211 | 'trims': trimAll, 212 | 'tel': phone_check, 213 | 'bankCard': checkUcredit, 214 | 'idCard': IdCardValidate, 215 | 'phone': checktel, 216 | 'date' : checkDate, 217 | 'email': checkEmail, 218 | 'QQ': checkQQ, 219 | 'name': checkName, 220 | 'ecode': checkECode 221 | } 222 | --------------------------------------------------------------------------------