小程序表单校验uni-forms
iamlujingtao 人气:0一、前言
小程序上使用表单理应是很常用,也很必须的功能,因为系统实用了uni-app,所以这时候会用到uni-forms,但使用过程中遇到不少问题。
这边的需求有3个:
即时校验(输入框失焦立即校验值)需自定义校验规则需要异步校验
满足这3个需求,就能实现绝大部分表单校验,然而直接使用官方的案例并不能满足,踩过不少坑,最后解决方案如下。
二、成果展示
以下展示均满足上述3个需求,下面示例代码可以直接看 第六点
三、uni-forms即时校验
实现即时校验,uni-forms需要加validate-trigger="bind"
,同时input添加@blur="binddata('字段名', $event.detail.value)"
示例:
<uni-forms ref="form" :modelValue="ruleForm" validate-trigger="bind"> <uni-forms-item label="账号" name="account"> <input v-model.trim="ruleForm.account" @blur="binddata('account', $event.detail.value)" placeholder="请输入您的登录账号" /> </uni-forms-item> </uni-forms>
四、uni-forms自定义校验规则
需要自定义校验规则时,去掉uni-forms的:rules,同时onReady里加this.$refs.form.setRules(this.rules)
,其中validateFunction: this.checkEmail为自定义校验方法
示例:
<template> <uni-forms ref="form" :modelValue="ruleForm" validate-trigger="bind"> ...... </uni-forms> </template> <script> export default { data() { return { // 校验规则 rules: { email: { rules: [ { validateFunction: this.checkEmail, }, ], }, }, }; }, onReady() { // 需要在onReady中设置规则 this.$refs.form.setRules(this.rules); }, methods: { /** * 表单验证邮箱 */ checkEmail(rule, value, allData, callback) { if (value !== "" && !verifyEmail(value)) { return callback("邮箱不正确"); } callback(); }, }, }; </script>
五、uni-forms异步校验
通常使用异步方法来校验账号是否重复等,步骤:
- 首先需要自定义校验方法validateFunction: this.checkAccount
- 然后进行常规的规则校验
- 再进行异步方法校验账号唯一性
需要使用Promise,校验通过使用 return resolve()
校验失败使用 return reject(new Error('错误提示信息'))
示例(核心代码部分):
export default { data() { return { // 校验规则 rules: { account: { rules: [ { required: true, errorMessage: '请输入您的账号', }, { validateFunction: this.checkAccount, }, ], }, }, }; }, methods: { // 表单验证账号 checkAccount(rule, value) { return new Promise((resolve, reject) => { // 先进行规则校验 if (value === '' || !verifyAccount(value)) { return reject(new Error('只能输入4-30位英文、数字、下划线')) } // 再进行异步校验,checkUser为本系统api异步方法,结合你系统使用你自己的方法 apiCheckAccount({ account: value }) .then((data) => { if (data.exist) { return reject(new Error('账号已存在')) } resolve() }) .catch((err) => { return reject(new Error(err.message)) }) }) }, },
六、完整示例源码
<template> <view class="register"> <view class="title">最实用表单校验</view> <uni-forms ref="form" :modelValue="ruleForm" validate-trigger="bind" label-width="40"> <uni-forms-item label="账号" name="account"> <input v-model.trim="ruleForm.account" @blur="binddata('account', $event.detail.value)" placeholder="请输入您的登录账号" /> </uni-forms-item> <uni-forms-item label="姓名" name="name"> <input v-model.trim="ruleForm.name" @blur="binddata('name', $event.detail.value)" placeholder="请输入您的姓名" /> </uni-forms-item> <uni-forms-item class="form-item-center"> <button type="primary" @click="submit()">注册</button> </uni-forms-item> </uni-forms> </view> </template> <script> import { apiCheckAccount } from '@/api' import { verifyAccount, verifyName } from '@/utils' export default { data() { return { // 表单数据 ruleForm: { account: '', // 账号 name: '', // 姓名 }, rules: {}, } }, onReady() { this.setRules() // 需要在onReady中设置规则 this.$refs.form.setRules(this.rules) }, methods: { // 提交表单 submit() { this.$refs.form .validate() .then(() => { uni.showToast({ title: '注册成功!', duration: 2000, icon: 'success', }) }) .catch((err) => { console.log('表单校验失败:', err) }) }, // 设置校验规则 setRules() { this.rules = { account: { rules: [ { required: true, errorMessage: '请输入您的账号', }, { validateFunction: this.checkAccount, }, ], }, name: { rules: [ { required: true, errorMessage: '请输入您的姓名', }, { validateFunction: this.checkName, }, ], }, } }, // 验证账号 checkAccount(rule, value) { return new Promise((resolve, reject) => { // 先进行规则校验 if (value === '' || !verifyAccount(value)) { return reject(new Error('只能输入4-30位英文、数字、下划线')) } // 再进行异步校验,checkUser为本系统api异步方法,结合你系统使用你自己的方法 apiCheckAccount({ account: value }) .then((data) => { if (data.exist) { return reject(new Error('账号已存在')) } resolve() }) .catch((err) => { return reject(new Error(err.message)) }) }) }, // 验证姓名 checkName(rule, value, allData, callback) { if (!verifyName(value)) { return callback('只能输入1-30位中英文和数字') } callback() }, }, } </script>
补充:记录一个uni-forms表单每输入一次就自动失去焦点的问题
局部代码:
我之前是在key里面放了个input变量进去了,这确实也是个低级错误,但是此类问题的原因应该大同小异,就是v-for底层map循环的时候,key值发生了变化,导致dom更新,出现这个问题,去掉不确定性的key值绑定就好了
所以,用key要谨慎啊!一不小心找bug就是半天过去了
最后
加载全部内容