给element plus中动态form-item增加校验的可行方法

element plus中的form组件自带校验机制。在常规使用场景中,表单项是固定的、明确的,且数量不会太多。校验规则的使用也如下:

<template>
	<div class="edit-page">
		<el-form :model="formModel" ref="formUser" label-position="top" label-width="auto" :inline="true"
			:rules="rules">
			<el-row :gutter="20">
				<el-col :sm="24" :md="12">
					<el-form-item label="账号" prop="loginId">
						<el-input v-model="formModel.loginId" autocomplete="off clearable/>
					</el-form-item>
				</el-col>
            </el-row>
    </el-form>
  </div>
</template>

<script setup>
....
const formModel = reactive({
      loginId:null
})

const rules = reactive({
		loginId: [{
				required: true,
				message: '账号还未填写',
				trigger: 'blur'
			},
			{
				min: 2,
				max: 20,
				message: '账号长度应该为2-20',
				trigger: 'blur'
			}
		]
})
</script>

校验规则在代码块单独定义,规则的匹配遵循:rules对象中的属性名与el-form-item 中prop属性名一致。(当然校验规则也可以在el-form-item行内定义)

但对应动态生成的el-form-item 如何增加校验规则呢?改用行内定义,具体方法如下:

<el-form-item :prop="xx"   :rules="{required: true, message: 'Please input Activity name', trigger: 'blur'}">....</el-form-item>

这里要重点说明prop的设置,这是给动态表单项增加校验的关键所在。

由于是动态生成表单项,所以代码可能如下

<el-form :model="arry">

        <template v-for="(item,index) in arry" :key="index">

                <el-form-item :prop="'['+index+'].name" :rules="{required: true,message: '名称还未填写',trigger: 'blur'}">
                    <el-input v-model="item.name">
                </el-form-item>

        </template>

代码说明:arry是数组类型的响应式对象如:

const arry=ref([{name:'a'},{name:'b'}])

这个arry可能是从后台接口返回的数据。所以由该数据生成的表单项是动态的。

根据推测,校验机制可能是这样的:

1.对于每个表单项要能确定其使用的校验规则,这个基本在定义阶段就可以确定下来(行内定义校验规则;或者单独定义且保证规则名与prop值一致);

2.在应用校验规则时要能获取到表单项的当前值。而表单项的当前值我们一般用v-model指令绑定到响应式数据对象上了。所以只要能取到对应的响应式数据即可。

这就体现prop属性的第二个作用了,定位响应数据的访问路径。(第一个作用是匹配校验规则)

通过<el-form :model="arry">    与  <el-form-item :prop="'['+index+'].name"> 中的 model属性值+prop属性值组合:"arry['"+index+'].name" 来确定数据访问路径。

这里可能会有疑问,为什么不能像<el-input v-model="">那样用v-for迭代过程中的变量,如上代码中的item来写:prop="item.name"。v-for及迭代变量item是渲染界面时用的。渲染完,item就不存在,不能访问了。而我们的校验是在渲染完后才启用的。必须保证后面阶段也能访问到对应数据。index渲染完也是不可访问的。只是上面的写法相当于把index当时的值固化下来了,是后面也能访问到。用的是字符串拼接来引用index,相当于闭包的作用。只要符合这样的机制,访问路径即便更复杂,比如双重迭代。也是可以使用自带校验的。

优化:上面介绍的规则定义是放在<el-form-item>行内定义的,在有些场景下,比如:一张大的填报报表,都是需要输入大于0的数值的。当然上面的表单项本身是动态生成的,手写规则的地方也不算多。为了验证猜想,及优化代码。能不能定义一个规则函数,将这个函数设置给 :rules属性。经过实验是可以的。

const ruleFloat=(msg)=>{
		return {
			pattern:/^\d+(\.\d+)?$/,
			message:`${msg}应为大于0的数值`,
			trigger:'blur'
		}
	}

而使用地方改为如下:

<el-form-item :rules="ruleFloat('身高')">

这样使用校验规则既满足了动态表单的需求,也最大限度地减少代码。

最后一点,在报表填报中,是不适合在输入框附近显示校验失败信息的。改为浮动弹框提示比较好。如用ElMessage.error('xx')。具体实现方式如下:

在<el-form>上设置属性,:show-message="false" 即关闭文本信息显示,增加校验事件处理函数@validate(每个表单项验证时都会触发该事件)

<el-form :show-message="false"  @validate="onValidate">

在处理函数中根据函数参数(prop,isValid,message)进行弹窗提示,详情看官方文档。

最后提交数据时,一般会调用表单对象的验证方法,这个方法会再对每个表单项进行验证,如有未验证通过的,会依次触发@validate事件,也就依次弹窗提示,体验不是很好。可以只弹一次给个笼统点的提示,如:还有校验未通过的数据,请先修改。此时可以设置个开关量,当个表单项输入时可以开启弹窗提示,提交表单时,就不用一个个提示了。

  • 20
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
如果您使用的是 element-plus 的表格和表单组件,并且需要进行校验,可以使用其提供的校验规则和自定义校验方法。 对于表格组件,您可以在列定义添加 `rules` 属性来设置校验规则,例如: ```html <el-table :data="tableData"> <el-table-column prop="name" label="姓名" :rules="[{ required: true, message: '请输入姓名', trigger: 'blur' }]"></el-table-column> <el-table-column prop="age" label="年龄" :rules="[{ required: true, message: '请输入年龄', trigger: 'blur' }, { type: 'number', message: '年龄必须为数字值' }]"></el-table-column> </el-table> ``` 在上述示例,我们为姓名和年龄两列设置了校验规则,其 `required` 表示必填,`type` 表示输入类型。当表格的数据被修改时,如果不符合校验规则,将会弹出相应的提示信息。 对于表单组件,您可以使用 `el-form` 组件的 `rules` 属性来设置校验规则,例如: ```html <el-form :model="form" :rules="rules"> <el-form-item label="姓名" prop="name"> <el-input v-model="form.name"></el-input> </el-form-item> <el-form-item label="年龄" prop="age"> <el-input v-model.number="form.age"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">提交</el-button> </el-form-item> </el-form> ``` 在上述示例,我们设置了一个 `form` 对象来存储表单数据,并为姓名和年龄两个字段设置了校验规则。当用户提交表单时,如果不符合校验规则,将会弹出相应的提示信息。 您还可以使用自定义校验方法来实现更复杂的校验逻辑,例如: ```html <el-form :model="form" :rules="rules"> <el-form-item label="密码" prop="password"> <el-input v-model="form.password" type="password"></el-input> </el-form-item> <el-form-item label="确认密码" prop="password2"> <el-input v-model="form.password2" type="password"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm">提交</el-button> </el-form-item> </el-form> ``` ```js data() { return { form: { password: '', password2: '' }, rules: { password: [ { required: true, message: '请输入密码', trigger: 'blur' }, { validator: this.validatePassword, trigger: 'blur' } ], password2: [ { required: true, message: '请再次输入密码', trigger: 'blur' }, { validator: this.validatePassword2, trigger: 'blur' } ] } } }, methods: { validatePassword(rule, value, callback) { if (value.length < 6 || value.length > 16) { callback(new Error('密码长度应为6-16位')) } else { callback() } }, validatePassword2(rule, value, callback) { if (value !== this.form.password) { callback(new Error('两次输入的密码不一致')) } else { callback() } }, submitForm() { this.$refs.form.validate(valid => { if (valid) { // 校验通过,提交表单 } else { // 校验不通过,弹出提示信息 } }) } } ``` 在上述示例,我们为密码和确认密码两个字段设置了自定义校验方法 `validatePassword` 和 `validatePassword2`,用于检查密码长度和两次输入的密码是否一致。在提交表单时,我们调用 `$refs.form.validate` 方法来进行校验,并根据校验结果来决定是否提交表单

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值