十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
如何在微信小程序中实现一个表单校验功能?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
宁明网站建设公司创新互联,宁明网站设计制作,有大型网站制作公司丰富经验。已为宁明成百上千家提供企业网站建设服务。企业网站搭建\成都外贸网站建设要多少钱,请找那个售后服务好的宁明做网站的公司定做!
表单校验之难
如果要问微信小程序最难实现的公共业务是什么?应该是表单校验,没有之一。原因如下:
表单组件在数量上达到11个,居各类组件之首。当然幸运的是,并不是所有的都需要校验。
而这些组件操作方式多样,可分为滑动、(多行)输入、点击、点击+滑动。
即使是同一个组件,因为业务场景不同就会有不同的校验规则。
更麻烦的是,这些组件之间经常还会联动或者关联校验。
…
但是,作为一个非简单静态页面,有着较多用户交互的小程序,表单校验又是一个非常常用的功能:登录、注册、新增、编辑…
总而言之:表单组件的多样性 X 校验规则的多样性 = 复杂的公共业务
这么棘手的问题我们怎么来解决它呢?
尝试组件化
如果你关注近年前端发展趋势,一定会想到“组件化”来实现:
把每个表单组件的视图、样式、校验逻辑封装成单独的业务组件,然后直接调用。
可事情似乎没这么简单。
如果考虑把n个原生组件抽象出来,配上n个校验规则,再乘以组件之间的关系n(的全排列),复杂度至少达到n³。
而且每个组件的校验失败或成功都要通知父组件,以便显示错误信息或者进行下一步操作。
这样不但没有解决问题,反而使得这些公用的表单组件过于复杂,耦合混乱。
尝试非组件化
既然原先的思路行不通,再来回到出发点,看看我们最核心的需要被抽象出来的是什么。
无非是两样东西:视图层的元素样式和逻辑层的校验规则。
上面说到封装原生表单组件会极大的增加复杂度,索性放弃它,复杂度瞬间可以下降到n²。
但同时我们又要保持样式统一,也就是我们常说的风格一致。
比如输入框该多高,错误提示怎么显示,字体大小颜色…之类的。
这个好办,我们把样式类写入一个公共样式文件form.wxss,然后需要的时候引入,甚至可以全局引入。
// form.wxss .form { display: block; font-size: 28rpx; position: relative; } .form-line { background-color: #fff; border-bottom: 1px solid #e5e5e5; font-size: 34rpx; height: 96rpx; line-height: 96rpx; display: flex; padding: 0 31rpx; } .form-title { box-sizing: border-box; background-color: #efefef; color: #838383; font-size: 28rpx; padding: 31rpx; min-height: 90rpx; } ...
我们使用的时候只需要在对应的元素上添加相应的样式即可。比如:
// xxx.wxml
那么接下来我们只剩下校验规则和组件关联关系之间这两个难题了。
校验规则理想的状态是可扩展和可配置。
可扩展。随着业务的增长,在不修改已有规则情况可以新增校验规则。
可配置。可单独为每个表单组件配置不同的单个或多个校验规则。
如何做到可定义?用统一的形式即可。比如:
/* 统一的格式: [规则名]: { rule: [校验方式] msg: [错误信息] } */ const validators = { // 简单的校验用正则 required: { rule: /.+/, msg: '必填项不能为空' }, // 复杂的校验用函数 same: { rule (val='', sVal='') { return val===this.data[sVal] }, msg: '密码不一致' } ... }
如何做到可配置?配置上支持类似数组的形式,然后用统一的函数依次读取这些校验规则,逐个校验。
配置的规则肯定是在原生表单组件上,至于组件的值也只能通过事件对象获取。
如果直接绑定事件进行校验会阻碍父页面获取值,所以最好由父页面绑定事件传值,并且传入事件对象和执行环境进行处理:
/* 校验函数部分代码 e 事件对象 context 页面对象函数执行的上下文环境 */ let validate = (e, context) => { // 从事件对象中获取组件的值 let value = (e.detail.value || '').trim() // 从事件中获取校验规则名称 let validator = e.currentTarget.dataset.validator ? e.currentTarget.dataset.validator .split(',') : [] // 遍历规则进行校验 for (let i = 0; i < validator.length; i++) { let ruleName = validator[i].split('=')[0] let ruleValue = validator[i].split('=')[1] let rule = validators[ruleName].rule || /.*/ if ('function' === typeof rule) { rule.call(context, value, ruleValue) ? '' : validators[ruleName].msg } else { rule.test(value) ? '' : validators[ruleName].msg } } ... }
调用起来也非常简单,按照固定的格式加上对应的样式,配置校验规则,然后调用校验函数。
// 部分代码示例 // page.wxml// page.js valid(e) { this.setData({ [e.currentTarget.dataset.name]: e.detail.value }) validate(e, this) }
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注创新互联行业资讯频道,感谢您对创新互联的支持。