element-ui[plus]使用动态表单,并为每个动态表单项添加验证
一个简单的例子
在使用ele-ui开发中,经常会用到对动态创建的表单进行字段验证,此时就需要使用到动态表单的验证,官方有示例,但是不够清晰。下面我将用一个简单的案例进行说明。
官方el-Form:https://element-plus.org/zh-CN/component/form.html
动态表单的校验:https://element-plus.org/zh-CN/component/form.html#添加-删除表单项
首先是HTML:
<el-form :model="form"
label-width="80px"
label-position="left"
size="large"
:rules="rules"
ref="hotForm"
v-loading.fullscreen.lock="waiting"
>
<div class="hot-item"
v-for="(hot, index) in form.hots"
:key="index"
:data-index="index + 1">
<el-form-item label="热搜词汇"
:prop="'hots.' + index + '.text'"
:rules="rules.text"
>
<el-input v-model="hot.text" placeholder="请输入您要设置的热搜词汇" />
</el-form-item>
<el-form-item label="热词类型"
:prop="'hots.' + index + '.stype'"
:rules="rules.stype"
>
<el-input v-model="hot.stype" placeholder="请输入热搜类型" />
</el-form-item>
<el-form-item label="操作">
<el-button type="warning" @click="insertItem(index)">
新增一条
</el-button>
<el-button type="danger" @click="deleteItem(index)">
删除此条
</el-button>
</el-form-item>
</div>
<el-form-item label="提交热搜">
<el-button type="primary" @click="submitForm">
<div class="save-btn">保存热搜</div>
</el-button>
</el-form-item>
</el-form>
然后是JS:
function checkChannel(channel) {
const allow = ['image', 'video', 'audio', 'font'];
if (allow.indexOf(channel) > -1) {
return true;
} else {
return false;
}
}
// 自定义验证类型
const checkStype = function (rule, value, callback) {
if (!value) {
let msg = '搜索词类型不能为空!';
return callback(new Error(msg));
}
if (!checkChannel(value)) {
let msg = '资源类型不正确';
return callback(new Error(msg));
}
callback();
}
export default {
name: "hotsearch",
data() {
return {
// :model必须是一个对象 虽然仅仅是一个数组 但是也要包装成对象
form: {
hots: []
},
rules: {
text: [
{ required: true, message: '热搜词汇不能为空!', trigger: 'blur' },
{ min: 2, max: 10, message: '热搜词汇长度请在2-10字之间', trigger: 'blur' },
],
stype: [
{ validator: checkStype, trigger: 'blur' }
]
},
waiting: false
}
},
created() {},
methods: {
submitForm() {
this.$refs.hotForm.validate(async (valid) => {
// 如果能通过验证
if (valid) {
this.waiting = true;
const hotsStr = JSON.stringify(this.form.hots);
const hotOk = await ...(hotsStr);
if (hotOk.success) {
setTimeout(() => {
this.waiting = false;
window.alert('热搜保存成功!');
}, 1000);
} else {
this.waiting = false;
window.alert('热搜保存失败');
}
}
// 当不能通过验证的时候
else {
window.alert('您的表单验证有误,请根据提示进行修改');
return;
}
});
},
deleteItem(index) {..},
insertItem(index) {..}
}
}
忽略掉一些乱七八糟的细节,我们看几个重点问题:
- form表单里的:model="form" :rules="rules" model和rules不能省略,而且这个model必须是个对象,虽然有时候我们仅仅需要的是一个数组,但是我们依然要包装成对象。
- 每一项必须绑定props!!! 这是重中之重。我好几次发现el-form不验证了,结果问题就出现在没有在el-form-item上绑定props!
<el-form-item label="用户名:" prop="username">
<el-input
placeholder="请输入您的登录密码"
size="large"
v-model="form.username"
autocomplete="off"
></el-input>
</el-form-item>
data() {
return {
form: {
// 这里的属性要与prop中的名称相同 才可以被验证
username: ""
}
}
}
在动态表单中,每一项都要绑定prop,这里就需要使用动态绑定了,一定要按照:
:prop="'hots.' + index + '.text'"
这种格式,hots是需要循环的数组键名(form.hots),index是循环时候的索引下标,而text是每个对象的字段名称(如下格式)。注意 之间要用点 . 来链接!比如:
form: {
hots: [
{
text: 'wubin.work',
stype: 'image
}
]
}
- 每一项必须单独绑定验证规则,如本例中的:rules="rules.stype",当然el-form也不要忘记绑定。
- prop和当前字段的字段名称要保持一致,无论动态还是静态表单都是。
- 验证规则不能用正则,可以考虑使用自定义验证
- 表单验证时,一定要有默认值,比如form里面的input绑定是form.value,则data中定义form时一定要加一个value,比如form: { value: '' }