动态增减表单--多个输入框校验

动态增减表单项里一层for循环里多个输入框校验

// 数据结构:dynamicValidateForm:{domains: [{msg:'',content:''},....]}
// model绑定的必须是个对象
<a-form-model
   :labelCol="{ span: 12 }"
    ref="dynamicValidateForm"
    @submit="handleSubmit"
    :model="dynamicValidateForm"
>
  <a-col v-for="(domain, index) in dynamicValidateForm.domains" :key="index">
     // prop字符串,必须是循环的key值(例如 domains)+index+要校验的值(例如:msg)。
     <a-form-model-item :prop="'domains.' + index + '.msg'" :rules="{required: true,message: '' }">
        <a-input v-model="domain.msg" placeholder="请输入" class="ml-10 mr-10 w-100" />
     </a-form-model-item>
     <a-form-model-item :prop="'domains.' + index + '.content'" :rules="{required: true,message: '' }">
        <a-input v-model="domain.content" placeholder="请输入" class="ml-10 mr-10 w-100" />
     </a-form-model-item>
  </a-col>
</a-form-model>

两层for循环里多个输入框校验

// 数据结构: dynamicValidateForm: {domains:[
//             {domain: [{msg:''},....]},
//             {domain: [{msg:''},....]},
//             {domain: [{msg:''},....]},
//             .....
//           ]},
// model绑定的必须是个对象
<a-form-model
   :labelCol="{ span: 12 }"
    ref="dynamicValidateForm"
    @submit="handleSubmit"
    :model="dynamicValidateForm"
>
  <a-row v-for="(domain, index) in dynamicValidateForm.domains" :key="index">
     <a-col v-for="(item,index2) in domain.domain" :key="index2">
       // prop字符串,拼接
       <a-form-model-item  :prop="'domains.' + index + '.domain.' + index2 + '.msg'" :rules="{required: true,message: ''  }">
          <a-input v-model="item.msg" placeholder="请输入" class="ml-10 mr-10 w-100" />
        </a-form-model-item>
      </a-col>
  </a-row>
</a-form-model>

// 如果需求要输入框报红,输入后马上变正常,validate-status可以实现

rules规则

<a-form-model :rules="formRules" :model="dynamicValidateForm">
  <a-form-model-item v-for="(domain, index) in dynamicValidateForm.domains" :key="index">
    <a-input v-model="domain.score"  placeholder="请输入" class="ml-10 mr-10 w-100" />
  </a-form-model-item>
</a-form-model

// formRules要和dynamicValidateForm.domains,结构一一对应,才能正常校验
formRules:{
	// domains是重点,0是变量,score是要校验的对象
	'domains.0.score': [
        { required: true, message: '请输入积分', trigger: 'blur' }
     ],
}
<think>我们正在使用Vue2和Element UI实现动态增减表单,并添加表单校验功能。 步骤: 1. 使用`el-form`组件,并设置`model`和`rules`。 2. 在`el-form`内部,使用`v-for`循环生成多个表单,每个表单对应动态表单的一个字段。 3. 为每个表单绑定`prop`,注意动态表单的`prop`应该是一个字符串,使用类似`'domains.' + index + '.value'`的形式。 4. 提供添加和删除表单的方法。 5. 在添加表单时,最好给每个表单一个唯一的key(例如使用index),这样在删除时不会出错。 6. 定义校验规则,注意动态数组的每个元素的校验规则。 注意:Element UI的表单校验对于动态生成的表单,需要确保每个表单的prop是唯一的,并且与rules中定义的规则路径一致。 示例代码结构: 模板部分: <el-form :model="dynamicForm" :rules="rules" ref="dynamicForm"> <div v-for="(domain, index) in dynamicForm.domains" :key="domain.key"> <el-form-item :prop="'domains.' + index + '.value'" :rules="rules.domains" > <el-input v-model="domain.value"></el-input> </el-form-item> <el-button @click.prevent="removeDomain(domain)">删除</el-button> </div> <el-button @click="addDomain">新增</el-button> </el-form> 数据部分: data() { return { dynamicForm: { domains: [] // 初始为空数组,每个元素是一个对象,如{ value: '' } }, rules: { domains: [ { required: true, message: '请输入内容', trigger: 'blur' } ] } }; }, methods: { addDomain() { this.dynamicForm.domains.push({ value: '', key: Date.now() // 使用时间戳作为key,确保唯一性 }); }, removeDomain(domain) { const index = this.dynamicForm.domains.indexOf(domain); if (index !== -1) { this.dynamicForm.domains.splice(index, 1); } } } 注意:这里我们为每个表单对象添加了一个key属性,用于v-for的key,这样在删除时不会因为索引变化而导致渲染问题。 但是,上面的校验规则rules.domains是一个数组,直接用在每个表单上。这样每个表单都会应用同样的校验规则。 如果需要更复杂的校验,比如每个表单可能有不同的规则,那么可以在rules中定义更复杂的结构,或者使用动态规则。 另外,在提交表单时,我们可以通过调用this.$refs.dynamicForm.validate()来校验整个表单。 完整示例: 模板: <template> <el-form :model="dynamicForm" :rules="rules" ref="dynamicForm" label-width="100px"> <el-form-item label="用户名"> <el-input v-model="dynamicForm.name"></el-input> </el-form-item> <div v-for="(domain, index) in dynamicForm.domains" :key="domain.key"> <el-form-item label="邮箱" :prop="'domains.' + index + '.value'" :rules="rules.email" > <el-input v-model="domain.value"></el-input> <el-button @click.prevent="removeDomain(domain)">删除</el-button> </el-form-item> </div> <el-form-item> <el-button type="primary" @click="submitForm('dynamicForm')">提交</el-button> <el-button @click="addDomain">新增邮箱</el-button> </el-form-item> </el-form> </template> 数据和方法: <script> export default { data() { return { dynamicForm: { name: '', domains: [] }, rules: { name: [ { required: true, message: '请输入用户名', trigger: 'blur' } ], email: [ { required: true, message: '请输入邮箱地址', trigger: 'blur' }, { type: 'email', message: '请输入正确的邮箱地址', trigger: ['blur', 'change'] } ] } }; }, methods: { submitForm(formName) { this.$refs[formName].validate((valid) => { if (valid) { alert('submit!'); } else { console.log('error submit!!'); return false; } }); }, addDomain() { this.dynamicForm.domains.push({ value: '', key: Date.now() }); }, removeDomain(domain) { const index = this.dynamicForm.domains.indexOf(domain); if (index !== -1) { this.dynamicForm.domains.splice(index, 1); } } } } </script> 注意:在动态表单中,我们为每个动态表单的prop指定了路径,如'domains.0.value',这样校验器就能找到对应的值。 另外,在rules中,我们直接使用了email规则数组,这样每个邮箱输入框都会应用同样的规则。 这样,我们就实现了动态增减表单并添加校验的功能。 相关问题: 1. 如果动态表单中每个表单校验规则不同,该如何处理? 2. 在动态表单中,如何实现整个表单校验? 3. 动态表单提交时,如何获取所有表单数据?</think>### Vue2 + Element UI 动态表单增减校验实现 下面是在 Vue2 中使用 Element UI 实现动态增减表单并添加校验的完整方案: #### 1. 基础模板结构 ```vue <template> <el-form :model="dynamicForm" :rules="formRules" ref="dynamicFormRef" label-width="100px" > <!-- 固定字段 --> <el-form-item label="用户名" prop="username"> <el-input v-model="dynamicForm.username" /> </el-form-item> <!-- 动态增减部分 --> <div v-for="(item, index) in dynamicForm.emails" :key="item.key" class="dynamic-item" > <el-form-item :label="`邮箱${index + 1}`" :prop="`emails.${index}.value`" :rules="emailRules" > <el-input v-model="item.value" /> <el-button type="danger" icon="el-icon-delete" @click="removeEmail(index)" circle ></el-button> </el-form-item> </div> <el-form-item> <el-button type="primary" @click="submitForm">提交</el-button> <el-button @click="addEmail">添加邮箱</el-button> </el-form-item> </el-form> </template> ``` #### 2. 数据与校验规则 ```javascript <script> export default { data() { // 邮箱字段校验规则 const validateEmail = (rule, value, callback) => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!value) { callback(new Error('邮箱不能为空')); } else if (!emailRegex.test(value)) { callback(new Error('请输入有效的邮箱地址')); } else { callback(); } }; return { dynamicForm: { username: '', emails: [{ value: '', key: Date.now() }] // 初始包含一个空 }, formRules: { username: [ { required: true, message: '用户名不能为空', trigger: 'blur' } ] }, emailRules: [ { validator: validateEmail, trigger: 'blur' } ] }; }, methods: { // 添加邮箱字段 addEmail() { this.dynamicForm.emails.push({ value: '', key: Date.now() // 使用时间戳确保唯一key }); }, // 移除邮箱字段 removeEmail(index) { if (this.dynamicForm.emails.length > 1) { this.dynamicForm.emails.splice(index, 1); } else { this.$message.warning('至少需要保留一个邮箱'); } }, // 表单提交 submitForm() { this.$refs.dynamicFormRef.validate(valid => { if (valid) { // 处理提交逻辑 console.log('表单数据:', JSON.parse(JSON.stringify(this.dynamicForm))); this.$message.success('提交成功!'); } else { this.$message.error('请检查表单填写'); return false; } }); } } }; </script> ``` #### 3. 关键实现细节 1. **动态字段管理**: - 使用数组 `emails` 存储动态字段 - 每个字段包含唯一 `key` 确保 Vue 正确追踪 - 通过 `addEmail()` 和 `removeEmail()` 增减字段 2. **校验规则绑定**: - 使用 `:prop="emails.${index}.value"` 语法绑定动态路径 - 自定义 `validateEmail` 函数实现邮箱格式校验 - 触发条件设置为 `blur`(焦点离开时校验) 3. **表单整体校验**: - 通过 `$refs.dynamicFormRef.validate()` 触发表单验证 - 自动处理所有字段(固定+动态)的校验状态 4. **UI/UX 优化**: - 删除按钮仅显示在可删除的字段上 - 保留至少一个动态字段的约束 - 使用 Element UI 的反馈消息提升体验 #### 4. 样式优化(可选) ```css <style scoped> .dynamic-item { position: relative; padding-right: 40px; } .el-button--danger { position: absolute; right: 0; top: 0; } </style> ``` #### 5. 常见问题解决 1. **校验不触发**: - 确保 `prop` 路径格式正确:`emails.0.value` - 检查动态字段是否包含在 `formRules` 或独立规则中 2. **删除后校验残留**: - 使用 `this.$refs.dynamicFormRef.clearValidate()` 清除校验状态 ```javascript removeEmail(index) { this.dynamicForm.emails.splice(index, 1); this.$nextTick(() => { this.$refs.dynamicFormRef.clearValidate(); }); } ``` 3. **复杂嵌套校验**: ```javascript // 多层级对象校验 :prop="`contacts.${index}.phone.value`" // 数组直接校验 :prop="`phones[${index}]`" ``` >[!TIP] >使用 Vue Devtools 实时检查表单数据结构和校验状态,能显著提高调试效率[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值