Vue+Element动态生成新表单并添加验证
我们有这样的需求,表单中默认有一条信息,用户可以再添加新的属性信息,这时候我们就需要用到动态表单,然后还添加动态验证规则。<el-form :model="formData3" :inline="true" ref="formData3" label-width=&am
我们有这样的需求,表单中默认有一条信息,用户可以再添加新的属性信息,这时候我们就需要用到动态表单,然后还添加动态验证规则。
访问在线 demo
点击新增属性就加一条数据
贴html的代码
<el-form :model="formData3" :inline="true" ref="formData3" label-width="65px" size="medium">
<el-row v-for="(item,index) in formData3.powerAttrList" :key="index">
<el-form-item label="参数名"
:prop="'powerAttrList.' + index + '.fieldDesc'"
:rules="[{ required: true, message: '参数名不能为空',trigger: 'change'},{max: 32, message: '不超过32个字符', trigger: 'change'}]">
<el-input v-model="item.fieldDesc" placeholder="请输入参数名"/>
</el-form-item>
<el-form-item label="描述"
:prop="'powerAttrList.' + index + '.fieldName'"
:rules="[{ required: true, message: '描述不能为空',trigger: 'change'},{max: 32, message: '不超过32个字符', trigger: 'change'}]">
<el-input v-model="item.fieldName" placeholder="请输入描述"/>
</el-form-item>
<el-form-item label="排序"
:prop="'powerAttrList.' + index + '.fieldSort'"
:rules="moreRules.fieldSort">
<el-input type="number" v-model="item.fieldSort" autocomplete="off" placeholder="请输入排序"/>
</el-form-item>
<el-button type="danger" v-if="formData3.powerAttrList.length > 1" size="medium" @click="removeRow(index)">
删除
</el-button>
</el-row>
<el-row>
<el-button type="primary" size="medium" @click="addRow">新增属性</el-button>
</el-row>
</el-form>
和普通表单验证不同的是,动态表单要新增自己的验证规则,和添加普通表单的方式一样
formData3: {
powerAttrList: [{
fieldName: '',
fieldSort: '',
fieldDesc: '',
}],
},
//新增表单的验证规则
moreRules: {
fieldSort: [{required: true, message: '请输入排序', trigger: 'change'},
{
validator: (rule, value, callback) => {
if (value < 0) {
callback(new Error('必须大于0'));
} else if (value.length > 5) {
callback(new Error('不超过5位数字'));
} else if (!value) {
callback(new Error('排序不能为空'));
} else {
callback();
}
},
trigger: 'change',
},
],
},
- 这里需要注意的是:
rules
是每个表单都要都要添加的,有多个的话就要给每个表单绑定一个规则,也可以行内编写和对象形式- 另外要注意的是
:prop
,正常表单验证单项是依靠prop
,但是动态生成话要用:prop
。
rules的写法和prop的写法见下面的代码
<el-form-item label="描述"
:prop="'powerAttrList.' + index + '.fieldName'"
:rules="[{required: true, message: '描述不能为空',trigger: 'change'},{max: 32, message: '不超过32个字符', trigger: 'change'}]">
<el-input v-model="item.fieldName" placeholder="请输入描述"/>
</el-form-item>
<el-form-item
label="排序"
:prop="'powerAttrList.' + index + '.fieldSort'"
:rules="moreRules.fieldSort">
<el-input type="number" v-model="item.fieldSort" placeholder="请输入排序"/>
</el-form-item>
书写的语法是 :prop="'powerAttrList.' + index +'.fieldSort'"
,powerAttrList
是v-for绑定的数组,index是索引,fieldSort
是表单绑定的v-model的名称,然后用 .
把他们链接起来。
所以总结起来的语法就是 :prop="'v-for绑定的数组.' + index + '.v-model绑定的变量'"
接下来就是js的data里的表单数据
v-for绑定的数组也要在表单的对象里,写在表单对象外是验证不了的,需要在data里添加
formData3: {
powerAttrList: [{
fieldName: '',
fieldSort: '',
fieldDesc: '',
}],
}
然后methods方法里新增属性列的函数应该这样写
// 添加属性列
addRow() {
this.formData3.powerAttrList.push({
fieldName: '',
fieldShowName: '',
fieldSort: '',
fieldDesc: '',
fieldType: '',
});
},
删除属性列的函数应该这样写
// 删除属性列
removeRow(index) {
this.formData3.powerAttrList.splice(index, 1);
},
全部代码贴上
注意前提是引用了element-ui哦
当然你们可以直接访问在线 demo
2020年补充:下面代码添加了下拉框和时间选择器的使用:
2021年补充:感谢评论老铁指出的错误,就是v-for循环 key 为index导致错误的验证提示,所以代码添加了唯一的key值取代数组索引index,所以最终代码如下
<template>
<div>
<el-form :model="formData3" :inline="true" ref="formData3" label-width="65px" size="medium">
<el-row
v-for="(item,index) in formData3.powerAttrList"
:key="item.key" // 更改前 :key="index"
style="border-bottom: 1px solid #f0f0f0;padding: 10px;"
>
<el-form-item
label="参数名"
:prop="'powerAttrList.' + index + '.fieldName'"
:rules="[{ required: true, message: '参数名不能为空',trigger: 'change'},{max: 32, message: '不超过32个字符', trigger: 'change'}]"
>
<el-input v-model="item.fieldName" placeholder="请输入参数名" />
</el-form-item>
<el-form-item
label="时间"
:prop="'powerAttrList.' + index + '.fieldTime'"
:rules="[{ required: true, message: '时间不能为空',trigger: 'change'}]"
>
<el-date-picker
v-model="item.fieldTime"
type="daterange"
start-placeholder="开始日期"
end-placeholder="结束日期"
value-format="yyyy-MM-dd"
:default-time="['00:00:00', '23:59:59']"
></el-date-picker>
</el-form-item>
<el-form-item
label="描述"
:prop="'powerAttrList.' + index + '.fieldDesc'"
:rules="[{ required: true, message: '描述不能为空',trigger: 'change'}]"
>
<el-select clearable v-model="item.fieldDesc" placeholder="请选择描述">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label="排序"
:prop="'powerAttrList.' + index + '.fieldSort'"
:rules="moreRules.fieldSort"
>
<el-input type="number" v-model="item.fieldSort" autocomplete="off" placeholder="请输入排序" />
</el-form-item>
<el-button
type="danger"
v-if="formData3.powerAttrList.length > 1"
size="medium"
@click="removeRow(index)"
>删除</el-button>
</el-row>
<el-row>
<el-button type="primary" size="medium" @click="addRow">新增属性</el-button>
<el-button type="primary" size="medium" @click="submit('formData3')">提交</el-button>
</el-row>
</el-form>
</div>
</template>
<script>
export default {
data() {
return {
// select下拉项
options: [
{
value: "选项1",
label: "黄金糕"
},
{
value: "选项2",
label: "双皮奶"
}
],
formData3: {
powerAttrList: [
{
fieldName: "",
fieldSort: "",
fieldDesc: "",
fieldTime: "",
key: Date.now() // 更改前没有
}
]
},
// 新增表单的验证规则
moreRules: {
fieldSort: [
{ required: true, message: "请输入排序", trigger: "change" },
{
validator: (rule, value, callback) => {
if (value < 0) {
callback(new Error("必须大于0"));
} else if (value.length > 5) {
callback(new Error("不超过5位数字"));
} else if (!value) {
callback(new Error("排序不能为空"));
} else {
callback();
}
},
trigger: "change"
}
]
}
};
},
methods: {
addRow() {
this.formData3.powerAttrList.push({
fieldName: "",
fieldSort: "",
fieldDesc: "",
fieldTime: "",
key: Date.now() // 更改前没有
});
},
// 删除属性列
removeRow(index) {
this.formData3.powerAttrList.splice(index, 1);
},
// 提交
submit(formName) {
this.$refs[formName].validate(valid => {
console.log(this.formData3);
if (valid) {
alert("submit!");
} else {
return false;
}
});
}
}
};
</script>
<style></style>
更多推荐
所有评论(0)