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();
				};
			},
    }
}
相关推荐
待磨的钝刨33 分钟前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
逐·風3 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫4 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦5 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子5 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山5 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享6 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
从兄7 小时前
vue 使用docx-preview 预览替换文档内的特定变量
javascript·vue.js·ecmascript
清灵xmf8 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨8 小时前
VUE+Vite之环境文件配置及使用环境变量
前端