Element?UI長表單校驗失敗后自動展開折疊面板并滾動定位代碼實現(xiàn)
前言
在復(fù)雜的后臺管理系統(tǒng)中,長表單常被拆分到多個 el-collapse 折疊面板中以提升可讀性。但當(dāng)用戶提交后出現(xiàn)校驗錯誤,如果錯誤字段藏在收起的面板里,僅靠 Element UI 默認(rèn)的高亮提示遠(yuǎn)遠(yuǎn)不夠——用戶根本看不到錯誤在哪!
本文將介紹一種 無需額外維護(hù)字段-面板映射關(guān)系 的自動化方案,實現(xiàn):自動展開包含錯誤字段的折疊面板 + 平滑滾動定位 + 自動聚焦,大幅提升用戶體驗。
問題場景
你是否遇到過這樣的情況?
- 表單字段多達(dá) 200+,為了界面整潔,用
el-collapse或者其他技術(shù)分成「基本信息」「聯(lián)系方式」「權(quán)限配置」等幾個面板; - 用戶填寫完前幾個字段,直接點「提交」;
- 后面面板中的必填項(如郵箱)校驗失敗,Element UI 給對應(yīng)
el-form-item加了紅色邊框; - 但該面板處于收起狀態(tài),用戶完全看不到錯誤提示,一臉懵……
此時,理想的行為應(yīng)該是:
- 自動展開包含第一個校驗錯誤字段的折疊面板;
- 頁面平滑滾動到該字段位置;
- (可選)讓輸入框獲得焦點,方便用戶立即修正。
而很多開發(fā)者會想到:我可以建一個 field → panelName 的映射表??!
但現(xiàn)實是:字段一多、結(jié)構(gòu)一變、動態(tài)表單一上,維護(hù)成本劇增,極易出錯。
有沒有更聰明的辦法?
核心思路:利用 DOM 結(jié)構(gòu)自動“溯源”
Element UI 的 el-collapse-item 渲染后是一個標(biāo)準(zhǔn)的 DOM 節(jié)點。如果我們能從 出錯的表單項 向上遍歷父節(jié)點,找到它所屬的折疊面板,就能知道該展開哪個面板。
但有個小坑:el-collapse-item 的 name 屬性不會直接出現(xiàn)在 DOM 中,所以我們需要手動加一個標(biāo)識。
解決方案三步走:
- 給每個
el-collapse-item添加data-panel-name屬性(值等于其name); - 校驗失敗時,找到第一個
.el-form-item.is-error元素; - 向上查找最近的
[data-panel-name]父元素,獲取面板名并展開; - 等待 DOM 更新后,滾動并聚焦。
全程 無需任何字段映射表,完全基于 DOM 結(jié)構(gòu)自動推斷!
代碼實現(xiàn)
1. 模板部分:添加data-panel-name
<template>
<el-form ref="formRef" :model="form" :rules="rules">
<el-collapse v-model="activePanels">
<!-- 注意:data-panel-name 的值必須和 name 一致 -->
<el-collapse-item
title="基本信息"
name="basic"
data-panel-name="basic"
>
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" />
</el-form-item>
</el-collapse-item>
<el-collapse-item
title="聯(lián)系方式"
name="contact"
data-panel-name="contact"
>
<el-form-item label="郵箱" prop="email">
<el-input v-model="form.email" />
</el-form-item>
</el-collapse-item>
</el-collapse>
<el-button type="primary" @click="handleSubmit">提交</el-button>
</el-form>
</template>?? 關(guān)鍵點:
data-panel-name是我們自定義的 DOM 標(biāo)識,用于后續(xù)查找。
2. 邏輯部分:自動展開 + 定位
export default {
data() {
return {
activePanels: ['basic'], // 初始展開的面板
form: { name: '', email: '' },
rules: {
name: [{ required: true, message: '請輸入姓名' }],
email: [{ required: true, message: '請輸入郵箱', type: 'email' }]
}
};
},
methods: {
handleSubmit() {
this.$refs.formRef.validate((valid, invalidFields) => {
if (!valid) {
this.$nextTick(() => {
const firstErrorItem = this.$el.querySelector('.el-form-item.is-error');
if (!firstErrorItem) return;
// 向上查找所屬面板
let panelName = null;
let parent = firstErrorItem.parentElement;
while (parent && parent !== document.body) {
const nameAttr = parent.getAttribute?.('data-panel-name');
if (nameAttr) {
panelName = nameAttr;
break;
}
parent = parent.parentElement;
}
// 如果面板未展開,則展開它
if (panelName && !this.activePanels.includes(panelName)) {
this.activePanels = [...this.activePanels, panelName];
// 等待面板展開完成后再滾動
this.$nextTick(() => {
this.scrollToErrorField(firstErrorItem);
});
} else {
// 面板已展開,直接滾動
this.scrollToErrorField(firstErrorItem);
}
});
} else {
console.log('? 提交成功');
}
});
},
scrollToErrorField(el) {
if (!el) return;
// 平滑滾動到視圖中央
el.scrollIntoView({ behavior: 'smooth', block: 'center' });
// 自動聚焦到輸入框(兼容 el-select 等組件)
const input = el.querySelector(
'input:not([type="hidden"]), textarea, .el-select__input'
);
input?.focus();
}
}
};方案優(yōu)勢
| 傳統(tǒng)方案 | 本文方案 |
|---|---|
| 需手動維護(hù) 字段 → 面板 映射表 | ? 無需任何映射,全自動推斷 |
| 動態(tài)表單難以適配 | ? 支持 v-for、異步加載等場景 |
| 易出錯、難維護(hù) | ? 基于 DOM 結(jié)構(gòu),穩(wěn)定可靠 |
| 僅支持單層折疊 | ? 可擴(kuò)展支持嵌套 Collapse |
擴(kuò)展建議
- 展開所有出錯面板:遍歷
invalidFields,收集所有錯誤字段對應(yīng)的面板名,批量展開; - 支持自定義滾動容器:若表單在
overflow: auto的 div 內(nèi),改用container.scrollTop = ...; - Vue 3 + Element Plus:邏輯完全一致,只需注意
ref和響應(yīng)式語法差異; - 封裝為通用方法:可抽離
autoScrollToError函數(shù),在多個表單中復(fù)用。
總結(jié)
長表單 + 折疊面板是后臺系統(tǒng)的常見組合,但校驗體驗不能因此打折。通過 利用 DOM 結(jié)構(gòu)向上溯源 + 自定義 data 屬性,我們實現(xiàn)了 零配置、全自動的錯誤定位與面板展開,既優(yōu)雅又實用。
好的交互細(xì)節(jié),往往就藏在這些“用戶看不見但能感受到”的地方。
到此這篇關(guān)于Element UI長表單校驗失敗后自動展開折疊面板并滾動定位的文章就介紹到這了,更多相關(guān)Element UI自動展開折疊面板滾動定位內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript的設(shè)計模式經(jīng)典之建造者模式
建造者模式是設(shè)計模式的一種,將一個復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。接下來通過本文給大家介紹JavaScript的設(shè)計模式經(jīng)典之建造者模式,感興趣的朋友一起學(xué)習(xí)吧2016-02-02
不使用JavaScript實現(xiàn)菜單的打開和關(guān)閉效果demo
本文通過實例代碼給大家分享在不使用JavaScript實現(xiàn)菜單的打開和關(guān)閉效果,非常不錯,具有參考借鑒價值,需要的朋友參考下吧2018-05-05
微信小程序?qū)崿F(xiàn)購物頁面左右聯(lián)動
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)購物頁面左右聯(lián)動,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-02-02
JScript中的"this"關(guān)鍵字使用方式補(bǔ)充材料
JScript中的"this"關(guān)鍵字使用方式補(bǔ)充材料...2007-03-03

