常见场景
表单时所有应用中不可缺少的组件,最近在使用element-ui的form组件时,遇到了想都没想到的问题
上代码
<template>
<div class="reset-password">
<div class="step" v-if="step == 1">
<div class="title">选择账号</div>
<div class="desc">
<template v-if="form.type == 'email'">请输入需要更改密码的邮箱号 </template>
<template v-else-if="form.type == 'phone'">请输入需要更改密码的手机号</template>
</div>
<el-form ref="verifyAccount" :model="form" :rules="formRules">
<el-form-item prop="password">
<el-input class="border-bottom" v-model="form.account"></el-input>
</el-form-item>
<el-form-item class="between">
<el-dropdown trigger="click" @command="changeAccountType">
<span class="el-dropdown-link">
账号类型:<span>{{ form.type == "phone" ? "手机" : "邮箱" }}</span>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="jdoc-icon-email" command="email">邮箱</el-dropdown-item>
<el-dropdown-item icon="jdoc-icon-mobile" command="phone">手机</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-button type="primary" @click="checkAccount">下一步</el-button>
</el-form-item>
</el-form>
</div>
<div class="step" v-else-if="step == 2">
<div class="title">验证身份</div>
<div class="desc">
<template v-if="form.type == 'email'">请输入邮件中的验证码 </template>
<template v-else-if="form.type == 'phone'">请输入你手机中最新收到的短信中的验证码</template>
</div>
<el-form ref="verifyAccount" :model="form" :rules="formRules">
<el-form-item prop="code">
<el-input class="border-bottom" max="6" v-model="form.code"></el-input>
</el-form-item>
<el-form-item prop="email">
<el-button type="primary" @click="checkCode">提交</el-button>
</el-form-item>
</el-form>
</div>
<div class="step" v-else-if="step == 3">
<div class="title">重置密码</div>
<div class="desc">请设置你的新密码</div>
<el-form ref="passwordForm" :model="form" :rules="formRules">
<el-form-item prop="password">
<el-input class="border-bottom" v-model="form.password"></el-input>
</el-form-item>
<el-form-item prop="email">
<el-button type="primary" @click="settingPassword">提交</el-button>
</el-form-item>
</el-form>
</div>
<div class="step" v-else-if="step == 4"></div>
</div>
</template>
<script>
export default {
data() {
const accountRule = (rule, value, callback) => {
if (this.form.type == "email") {
// 验证邮箱号
if (/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(.[a-zA-Z0-9_-])+/.test(value)) {
callback();
} else {
callback(new Error("请输入正确的邮箱号"));
}
} else if (this.form.type == "phone") {
// 验证手机号
if (/^[1][3,4,5,6.7,8,9][0-9]{9}$/.test(value)) {
callback();
} else {
callback(new Error("请输入正确的手机号"));
}
}
};
return {
step: 1,
form: {
type: "email",
account: "",
code: "",
password: ""
},
formRules: {
acc: [{ validator: accountRule, trigger: "blur" }],
pssword: [{ required: true, message: "请输入新密码", trigger: "blur" }],
code: [
{ required: true, message: "请输入验证码", trigger: "blur" },
{ min: 6, max: 6, message: "请输入正确的验证码" }
]
}
};
},
watch: {
"form.type": function () {
this.$refs.verifyAccount.resetFields();
}
},
};
</script>
在上面的watch中,我设置了如果form.type改变,就重置verifyAccount表单,但。。然并卵,emmmmm
解决问题
踩坑第一步:ref重复
可以看到两个表单的ref相同,而第二个会在第一个验证通过后才会挂载到页面,所以当操作ref时是获取不到组件的,所以所有方法都不会起效
踩坑第二步:prop 不一致
可以看到el-form-item 的prop属性值和el-input v-model属性值,是不一样的,需要将password改为account,不然form验证时找不到对应关系
踩坑第三步:el-form model 绑定属性中的字段名称和rules绑定属性中的字段名不一样
可以看到form中的account 和formRules中的acc不对应,需要将formRules中的acc改为account
一失足成,而千古恨,细心,细心
总结
- 检查form绑定的ref是否重复
- 检查el-form-item的prop属性和录入组件绑定的值是否匹配
- 检查form组件model属性值和rules属性值中的字段名是否匹配
建议
在做多步骤表单验证时,每个步骤如果只需要验证model中的个别字段时,建议将字段拆开放在多个表单组件中,这样方便处理表单验证,避免使用validateField验证多个字段,产生不必要的逻辑BUG;
validateField:在验证多字段时,是采用多次执行validate回调方法的验证方式,所以不方便做最终的验证处理