element-plus验证不通过自动滚动到第一个错误出现的位置

884 阅读1分钟

核心功能:使用vue3+element-plus()+scrollIntoView实现多表单验证,当规则校验不通过,浏览器滚动到第一个错误出现的位置。

界面ui还原稿如下:可以看到,这个界面是由多个form表单遍历出来的,当点击“保存并退出”和“完成并推送”时,需校验每个表单的规则必须满足条件后方可提交。

image.png

此功能实现步骤可以拆解为3步:

1.对遍历出来的表单对象添加动态的ref

 <div v-for="(item, index) in saveOrUpdateList" class="item">
       <form-wegit :model="item" :ref="setRef(index)" :showSubmit="false" :form-list="formItem"></form-wegit>
</div>

const dynamicRefs = ref([])

const setRef = (index) => {
    return (el) => dynamicRefs.value[index] = el;
}

2.对表单进行批量规则校验

const checkData = async () => {
    if (saveOrUpdateList.value.length <= 0) {
        ElMessage.error("问答对不能为空");
        return;
    }
    dynamicRefs.value = dynamicRefs.value.filter((i) => i);
    let flag = true;
    for (const i of dynamicRefs.value) {
        if (!flag) break;
        await i.getFormRef().validate(async (valid) => {
            if (!valid) {
                ElMessage.error("表单内容验证规则不通过,请修改");
                await nextTick();
                const isError = document.getElementsByClassName('is-error');
                if (isError[0]) {
                    isError[0].scrollIntoView({
                        behavior: 'smooth',
                        block: 'center',
                    });
                }
                flag = false;
                return;
            }
        });

        if (!flag) break;
    }
    return flag;
};

3.验证不满足时,自动滚动到第一个错误出现的位置

const isError = document.getElementsByClassName('is-error');
if (isError[0]) {
    isError[0].scrollIntoView({
        behavior: 'smooth',
        block: 'center',
    });
}

3.1 更新评论区同学提到的另外一种方法:

await i.getFormRef().validate(async (valid, errors) => {
    if (!valid) {
        ElMessage.error("表单内容验证规则不通过,请修改");
        const firstErrorField = Object.keys(errors)[0];
        console.log(firstErrorField, "firstErrorField")
        i.getFormRef().scrollToField(firstErrorField)
        flag = false;
        return;
    }
    });

这种方法更简洁,但是我没找到办法实现上述方法block: 'center'的效果,故仍采用了3的方法。

image.png

3.1实现的效如下:

image.png