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();
				};
			},
    }
}
相关推荐
长风清留扬19 分钟前
小程序毕业设计-音乐播放器+源码(可播放)下载即用
javascript·小程序·毕业设计·课程设计·毕设·音乐播放器
web1478621072333 分钟前
C# .Net Web 路由相关配置
前端·c#·.net
m0_7482478033 分钟前
Flutter Intl包使用指南:实现国际化和本地化
前端·javascript·flutter
飞的肖37 分钟前
前端使用 Element Plus架构vue3.0实现图片拖拉拽,后等比压缩,上传到Spring Boot后端
前端·spring boot·架构
青灯文案144 分钟前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
m0_748254881 小时前
DataX3.0+DataX-Web部署分布式可视化ETL系统
前端·分布式·etl
ZJ_.1 小时前
WPSJS:让 WPS 办公与 JavaScript 完美联动
开发语言·前端·javascript·vscode·ecmascript·wps
GIS开发特训营1 小时前
Vue零基础教程|从前端框架到GIS开发系列课程(七)响应式系统介绍
前端·vue.js·前端框架·gis开发·webgis·三维gis
Cachel wood2 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
学代码的小前端2 小时前
0基础学前端-----CSS DAY9
前端·css