参考文章:element表单校验新玩法:一键定位未通过字段位置_修改 element form表单验证信息位置-CSDN博客
表单校验:当表单校验未通过时,能够直接定位到未通过字段位置,能够让用户快速找到错误的地方进行修改,方便用户操作提高用户的效率。
文章目录
实现效果:
效果1:
效果2:
主要步骤:
1. 在必填校验的el-form-item元素中添加ref
ref 作用主要是用来定位(ref 的值建议与 prop 同名)
代码如下:
<el-form ref="formRef" :model="state.form" class="formTable">
<div class="FormLine h35">
<div class="FormLabel">信息来源</div>
<div class="FormContent">
<el-form-item prop="shangbaolx" ref="shangbaolx" :rules="[{ required: true, message: '【信息来源】不能为空', trigger: 'change' }]">
<el-select v-model="state.form.shangbaolx" size="large" placeholder="">
<el-option v-for="item in informationSources" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
</div>
<div class="FormLabelSec">当事人</div>
<div class="FormContent w105">
<el-form-item prop="shijianzt" ref="shijianzt" :rules="[{ required: true, message: '【当事人】不能为空', trigger: 'blur' }]">
<el-input v-model="state.form.shijianzt" type="text" />
</el-form-item>
</div>
<div class="FormContentThird">
<el-checkbox v-model="unknown" label="未知" size="large" />
</div>
</div>
<div class="FormLine h70">
<div class="FormLabel">事件描述</div>
<div class="FormContentLong h70">
<el-form-item prop="shiJianms" ref="shiJianms" :rules="[{ required: true, message: '【事件描述】不能为空', trigger: 'blur' }]">
<el-input :rows="2" v-model="state.form.shiJianms" :cols="40" type="textarea" placeholder="请输入事件描述……" />
</el-form-item>
</div>
</div>
<div class="FormLine h70">
<div class="FormLabel">事件备注</div>
<div class="FormContentLong h70">
<el-form-item prop="beizhu" ref="beizhu" :rules="[{ required: true, message: '【事件备注】不能为空', trigger: 'blur' }]">
<el-input :rows="2" v-model="state.form.beizhu" :cols="40" type="textarea" placeholder="请输入事件备注……" />
</el-form-item>
</div>
</div>
</el-form>
<div class="bottomArea">
<el-button type="primary" @click="register" size="default">登记</el-button>
</div>
提示:如果只想实现效果1,那么到此就可以结束了(效果1的实现只需添加rules规则,当鼠标点击失焦后显示红框和提示字):
2. 把提交校验的validate方法进行封装,在提交的时候先调用校验方法进行非空判断;
弹框显示未填写的字段
代码如下:
const register = async () => {
formRef.value.validate(async (valid: boolean, object) => {
if (valid) {
//校验通过执行逻辑
} else {
nextTick(() => {
let str = []
for (let key in object) {
object[key].map((item) => {
str.push(item.message)
})
let dom = Object.keys(object)[0].valueOf
if (Object.prototype.toString.call(dom) !== '[object Object]') {
dom = dom[0]
break //结束语句并跳出语句,进行下个语句执行
}
// 定位代码
dom.$el.scrollIntoView({
block: 'center',
behavior: 'smooth',
})
}
// 页面提示未通过校验字段项,并以逗号分隔
ElMessage.error(str.join(','))
})
}
if (!valid) {
ElMessage.error({ message: '请检查将表格输入完整', grouping: true })
return
}
})
}
3. 应甲方要求去除红框和下方提示
因为甲方爸爸觉得红色提示框太多太乱,决定以弹窗提示的方式进行,由于本人技术有限,没有什么好的方法,直接使用了原始的css样式进行样式隐藏(如果大佬们有更好的方法,欢迎来讨论TAT)
/*--------验证-不显示红框和提示--------*/
::v-deep .el-form-item.is-error .el-select__wrapper {
box-shadow: 0 0 0 0px;
}
::v-deep .el-form-item.is-error .el-textarea__inner {
box-shadow: 0 0 0 0px;
}
::v-deep .el-form-item.is-error .el-input__wrapper {
box-shadow: 0 0 0 0px;
}
::v-deep .el-form-item__error {
opacity: 0;//透明度(即提示字不显示)
}
总结
*总体思路:
1、给提交事件添加一个参数 object ;
2、当校验不通过时收集所有未通过字段项提示信息,将其通过 push 方法添加到定义好的数组中(str);
3、通过 Object.keys(object)[0].valueOf
获取到首个字段校验不通过的提示信息;
4、利用Object.prototype.toString.call()
方法判断 Object.keys(object)[0].valueOf
的类型是否为对象的字符串形式;
5、最后通过 scrollIntoView 方法滚动到首个不通过校验字段项。
!!温馨提示:如果在必填项里面使用了v-show或者v-if判断,一定一定要选择v-if来进行判断(使用v-show,即使元素被隐藏依旧会被dom捕获,从而提示该元素未填写)