动态增减输入框并做校验
仅做记录之用
<template><el-formref="createForm":model="createForm":rules="formRules"label-width="180px"style="max-width: 800px"><!-- 动态 --><div v-for="(switchItem, index) in createForm.switches" :key="index" style="margin-bottom: 16px"><el-row :gutter="20"><el-col :span="10"><el-form-itemlabel="名称":prop="`switches.${index}.switch_name`"><el-input v-model="switchItem.switch_name" placeholder="名称" /></el-form-item></el-col><el-col :span="10"><el-form-itemlabel="IP":prop="`switches.${index}.switch_ip`"><el-input v-model="switchItem.switch_ip" placeholder="如:192.168.1.10" /></el-form-item></el-col><el-col :span="4" style="display: flex; align-items: center"><el-buttontype="primary"size="small"icon="el-icon-plus"@click="addSwitch"></el-button><el-buttonv-if="createForm.switches.length > 1"type="danger"size="small"icon="el-icon-minus"@click="removeSwitch(index)"></el-button></el-col></el-row></div><el-form-item><el-button type="primary" @click="add"> 添加</el-button><el-button type="success" @click="submitForm">提交</el-button></el-form-item></el-form>
</template><script>
export default {name: 'createForm',data() {return {createForm: {switches: [{ switch_name: '', switch_ip: '' }],},// ⭐️ 手动管理 rules,避免 computed 不响应formRules: {}};},computed: {// 生成完整校验规则generateRules() {const staticRules = {//其他参数};const dynamicRules = {};this.createForm.switches.forEach((_, index) => {// 名称dynamicRules[`switches.${index}.switch_name`] = [{ required: true, message: `第${index + 1}个名称不能为空`, trigger: 'blur' }];// IP(含格式 + 唯一性校验)dynamicRules[`switches.${index}.switch_ip`] = [{ required: true, message: `第${index + 1}个IP不能为空`, trigger: 'blur' },{validator: (rule, value, callback) => {if (!value) {callback();return;}// 格式校验const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/;if (!ipv4Regex.test(value)) {callback(new Error('请输入有效的IPv4地址'));return;}const parts = value.split('.').map(Number);if (parts.some(part => isNaN(part) || part < 0 || part > 255)) {callback(new Error('IP地址每段必须在0-255之间'));return;}// 唯一性校验:检查是否与其他IP重复const ipList = this.createForm.switches.map(s => s.switch_ip);const sameCount = ipList.filter(ip => ip === value).length;if (sameCount > 1) {callback(new Error('IP不能重复'));} else {callback();}},trigger: 'blur'}];});return { ...staticRules, ...dynamicRules };}},watch: {// 监听 switches 变化,更新 rules'createIbNetGroupForm.switches': {handler() {this.formRules = this.generateRules;},deep: true}},methods: {addSwitch() {this.createForm.switches.push({ switch_name: '', switch_ip: '' });},removeSwitch(index) {this.createForm.switches.splice(index, 1);},submitForm() {this.$refs.createForm.validate(valid => {if (valid) {this.$message.success('✅ 提交成功!');console.log('提交数据:', this.createForm);// TODO: 调用 API} else {this.$message.error('❌ 表单校验未通过');}});}},mounted() {// 初始化规则this.formRules = this.generateRules;}
};
</script><style scoped>
.el-divider {margin: 24px 0;
}
</style>
