uniapp + uView动态表单校验

项目需求:动态循环表单,并实现动态表单校验

页面:

javascript 复制代码
		<u--form label-position="top" :model="tmForm" ref="tmForm" label-width="0px" :rules='rules'>
			<div v-for="(element, index) in tmForm.tmList.filter((item) => item.delFlag !== 1)" :key="index"
				class="form-item">
				<div v-if="element.txTip == 'Input'">{{ element.tmTitle }}</div>
				<u-form-item :required="element.pz.sfBt == '0'" :prop="`tmList[${index}].value`"
					:label="`第${getFilteredIndex(index)}题`" v-if="element.txTip != 'Input'">
					<div class="tm-title">{{ element.tmTitle }}</div>
					<div class="tm-sm" v-if="element.tmSm">题目说明:{{ element.tmSm }}</div>
					<div class="tm-sm" v-if="element.txTip == 'Textarea'">
						题目规则:请填写『{{ element.pz.zfMin }} ~ {{ element.pz.zfMax }}』个字
					</div>
					<div class="tm-sm" v-if="element.txTip == 'InputNumber'">
						题目规则:请填写『{{ element.pz.szMin }} ~ {{ element.pz.szMax }}』之间,小数点不超过{{
		                  element.pz.szDeciPlace
		                }}位的数
					</div>
					<div class="tm-sm" v-if="element.txTip == 'CheckBox' || element.txTip == 'twCheckBox'">
						题目规则:请选择『{{ element.pz.dxMin }} ~ {{ element.pz.dxMax }}』个选项
					</div>
					<div class="tm-sm" v-if="element.txTip == 'TimePicker'">
						题目规则:请选择『{{ element.pz.rqMin }} ~ {{ element.pz.rqMax }}』之间的时间
					</div>
					<div class="tm-sm" v-if="element.txTip == 'Upload'">
						题目规则:请上传『{{ element.pz.dxMin }} ~ {{ element.pz.dxMax }}』张图片
					</div>
					<component style="margin-top: 10upx;" :optionList="element.optionList" :options="element.pz"
						v-model="element.value" :is="getWidget(element.txTip)"
						@updateValue="(newValue) => updateValue(element, newValue)"></component>
				</u-form-item>
			</div>
		</u--form>

直接给rules里面循环加上校验规则,注意页面prop的写法 :prop="`tmList[${index}].value`"

javascript 复制代码
	export default {
		data() {
			return {
				tmForm: {
					tmList: []
				},
				rules: {}
			}
		},
		mounted() {
			this.setRules()
		},
		methods: {
			// 循环设置rules
			setRules() {
				this.tmForm.tmList.forEach((ele, index) => {
					this.$set(this.rules, `tmList[${index}].value`, [
						{
							validator: this.validate(ele),
							trigger: 'change'
						}
					])
				}),
		},

     			// 表单验证方法
			validate(element) {
				return (rule, value2, callback) => {
                    let value = element.value  //value2是空的,我手动赋值了

					if (element.pz.sfBt === '0' && (!value || value.length < 1)) {
						callback(new Error("请输入"));
						return;
					}

					if (element.txTip == "Textarea") {
						if (value && value.length > element.pz.zfMin) {
							callback(); // 通过验证
						} else {
							callback(new Error("文本长度不能小于10位"));
						}
					}

					if (element.txTip == "InputNumber") {
						const regex = new RegExp(`^-?\\d+(\\.\\d{0,${element.pz.szDeciPlace}}})*$`);
						// 判断是否在指定范围内且满足小数点位数要求
						if (value >= element.pz.szMin && value <= element.pz.szMax && regex.test(value)) {
							callback(); // 通过验证
						} else {
							callback(
								new Error(
									`请输入『${element.pz.szMin} ~ ${element.pz.szMax}』之间,小数点不超过${element.pz.szDeciPlace}位的数`
								)
							); // 验证失败
						}
					}

					if (element.txTip == "CheckBox" || element.txTip == "twCheckBox") {
						if (value.length >= element.pz.dxMin && value.length <= element.pz.dxMax) {
							console.log(1);
							callback(); // 通过验证
						} else {
							callback(new Error(`请选择『${element.pz.dxMin} ~ ${element.pz.dxMax}』个选项`)); // 验证失败
							console.log(2);
						}
					}

					if (element.txTip == "Upload") {
						const imageUrls = value.split(","); // 将图片 URL 字符串拆分为数组
						if (imageUrls.length >= element.pz.dxMin) {
							callback(); // 验证通过
						} else {
							callback(new Error(`请至少上传 ${element.pz.dxMin} 张图片`)); // 验证失败
						}
					}

					if (element.txTip == "Address" && element.pz.sfXxdz == "0") {
						if (value.value2) {
							callback(); // 验证通过
						} else {
							callback(new Error(`请填写详细地址`)); // 验证失败
						}
					}

					if (element.txTip == "PhoneNumber") {
						const reg = /^1[3-9]\d{9}$/; // 定义手机号码的正则表达式
						if (reg.test(value)) {
							callback(); // 验证通过
						} else {
							callback(new Error("手机号码格式不正确")); // 验证失败
						}
					}

					if (element.txTip == "IdNumber") {
						const reg = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/; // 定义身份证号码的正则表达式
						if (reg.test(value)) {
							callback(); // 验证通过
						} else {
							callback(new Error("身份证号码格式不正确")); // 验证失败
						}
					}

					if (element.txTip == "Email") {
						const reg = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/; // 定义邮箱地址的正则表达式
						if (reg.test(value)) {
							callback(); // 验证通过
						} else {
							callback(new Error("邮箱地址格式不正确")); // 验证失败
						}
					}

					callback();
				};
			},
    }
}
相关推荐
艾小码8 小时前
前端路由的秘密:手写一个迷你路由,看懂Hash和History的较量
前端·javascript
偷光10 小时前
浏览器中的隐藏IDE: Elements (元素) 面板
开发语言·前端·ide·php
江拥羡橙15 小时前
Vue和React怎么选?全面比对
前端·vue.js·react.js
千码君201615 小时前
React Native:快速熟悉react 语法和企业级开发
javascript·react native·react.js·vite·hook
楼田莉子17 小时前
Qt开发学习——QtCreator深度介绍/程序运行/开发规范/对象树
开发语言·前端·c++·qt·学习
暮之沧蓝17 小时前
Vue总结
前端·javascript·vue.js
木易 士心17 小时前
Promise深度解析:前端异步编程的核心
前端·javascript
im_AMBER17 小时前
Web 开发 21
前端·学习
又是忙碌的一天17 小时前
前端学习day01
前端·学习·html
Joker Zxc17 小时前
【前端基础】20、CSS属性——transform、translate、transition
前端·css