最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Element?UI長(zhǎng)表單校驗(yàn)失敗后自動(dòng)展開(kāi)折疊面板并滾動(dòng)定位代碼實(shí)現(xiàn)

 更新時(shí)間:2026年04月10日 10:11:21   作者:志摩凜  
折疊面板是一種常見(jiàn)的界面組件,用于在有限的空間內(nèi)展示大量?jī)?nèi)容,并允許用戶通過(guò)折疊和展開(kāi)的方式進(jìn)行內(nèi)容的查看和操作,這篇文章主要介紹了Element UI長(zhǎng)表單校驗(yàn)失敗后自動(dòng)展開(kāi)折疊面板并滾動(dòng)定位的相關(guān)資料,需要的朋友可以參考下

前言

在復(fù)雜的后臺(tái)管理系統(tǒng)中,長(zhǎng)表單常被拆分到多個(gè) el-collapse 折疊面板中以提升可讀性。但當(dāng)用戶提交后出現(xiàn)校驗(yàn)錯(cuò)誤,如果錯(cuò)誤字段藏在收起的面板里,僅靠 Element UI 默認(rèn)的高亮提示遠(yuǎn)遠(yuǎn)不夠——用戶根本看不到錯(cuò)誤在哪!

本文將介紹一種 無(wú)需額外維護(hù)字段-面板映射關(guān)系 的自動(dòng)化方案,實(shí)現(xiàn):自動(dòng)展開(kāi)包含錯(cuò)誤字段的折疊面板 + 平滑滾動(dòng)定位 + 自動(dòng)聚焦,大幅提升用戶體驗(yàn)。

問(wèn)題場(chǎng)景

你是否遇到過(guò)這樣的情況?

  • 表單字段多達(dá) 200+,為了界面整潔,用 el-collapse或者其他技術(shù)分成「基本信息」「聯(lián)系方式」「權(quán)限配置」等幾個(gè)面板;
  • 用戶填寫(xiě)完前幾個(gè)字段,直接點(diǎn)「提交」;
  • 后面面板中的必填項(xiàng)(如郵箱)校驗(yàn)失敗,Element UI 給對(duì)應(yīng) el-form-item 加了紅色邊框;
  • 但該面板處于收起狀態(tài),用戶完全看不到錯(cuò)誤提示,一臉懵……

此時(shí),理想的行為應(yīng)該是:

  1. 自動(dòng)展開(kāi)包含第一個(gè)校驗(yàn)錯(cuò)誤字段的折疊面板;
  2. 頁(yè)面平滑滾動(dòng)到該字段位置
  3. (可選)讓輸入框獲得焦點(diǎn),方便用戶立即修正。

而很多開(kāi)發(fā)者會(huì)想到:我可以建一個(gè) field → panelName 的映射表?。?br />但現(xiàn)實(shí)是:字段一多、結(jié)構(gòu)一變、動(dòng)態(tài)表單一上,維護(hù)成本劇增,極易出錯(cuò)。

有沒(méi)有更聰明的辦法?

核心思路:利用 DOM 結(jié)構(gòu)自動(dòng)“溯源”

Element UI 的 el-collapse-item 渲染后是一個(gè)標(biāo)準(zhǔn)的 DOM 節(jié)點(diǎn)。如果我們能從 出錯(cuò)的表單項(xiàng) 向上遍歷父節(jié)點(diǎn),找到它所屬的折疊面板,就能知道該展開(kāi)哪個(gè)面板。

但有個(gè)小坑:el-collapse-itemname 屬性不會(huì)直接出現(xiàn)在 DOM 中,所以我們需要手動(dòng)加一個(gè)標(biāo)識(shí)。

解決方案三步走:

  1. 給每個(gè) el-collapse-item 添加 data-panel-name 屬性(值等于其 name);
  2. 校驗(yàn)失敗時(shí),找到第一個(gè) .el-form-item.is-error 元素;
  3. 向上查找最近的 [data-panel-name] 父元素,獲取面板名并展開(kāi);
  4. 等待 DOM 更新后,滾動(dòng)并聚焦。

全程 無(wú)需任何字段映射表,完全基于 DOM 結(jié)構(gòu)自動(dòng)推斷!

代碼實(shí)現(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)鍵點(diǎn)data-panel-name 是我們自定義的 DOM 標(biāo)識(shí),用于后續(xù)查找。

2. 邏輯部分:自動(dòng)展開(kāi) + 定位

export default {
  data() {
    return {
      activePanels: ['basic'], // 初始展開(kāi)的面板
      form: { name: '', email: '' },
      rules: {
        name: [{ required: true, message: '請(qǐng)輸入姓名' }],
        email: [{ required: true, message: '請(qǐng)輸入郵箱', 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;
            }
            // 如果面板未展開(kāi),則展開(kāi)它
            if (panelName && !this.activePanels.includes(panelName)) {
              this.activePanels = [...this.activePanels, panelName];
              // 等待面板展開(kāi)完成后再滾動(dòng)
              this.$nextTick(() => {
                this.scrollToErrorField(firstErrorItem);
              });
            } else {
              // 面板已展開(kāi),直接滾動(dòng)
              this.scrollToErrorField(firstErrorItem);
            }
          });
        } else {
          console.log('? 提交成功');
        }
      });
    },
    scrollToErrorField(el) {
      if (!el) return;
      // 平滑滾動(dòng)到視圖中央
      el.scrollIntoView({ behavior: 'smooth', block: 'center' });
      // 自動(dòng)聚焦到輸入框(兼容 el-select 等組件)
      const input = el.querySelector(
        'input:not([type="hidden"]), textarea, .el-select__input'
      );
      input?.focus();
    }
  }
};

 方案優(yōu)勢(shì)

傳統(tǒng)方案本文方案
需手動(dòng)維護(hù) 字段 → 面板 映射表? 無(wú)需任何映射,全自動(dòng)推斷
動(dòng)態(tài)表單難以適配? 支持 v-for、異步加載等場(chǎng)景
易出錯(cuò)、難維護(hù)? 基于 DOM 結(jié)構(gòu),穩(wěn)定可靠
僅支持單層折疊? 可擴(kuò)展支持嵌套 Collapse

擴(kuò)展建議

  • 展開(kāi)所有出錯(cuò)面板:遍歷 invalidFields,收集所有錯(cuò)誤字段對(duì)應(yīng)的面板名,批量展開(kāi);
  • 支持自定義滾動(dòng)容器:若表單在 overflow: auto 的 div 內(nèi),改用 container.scrollTop = ...;
  • Vue 3 + Element Plus:邏輯完全一致,只需注意 ref 和響應(yīng)式語(yǔ)法差異;
  • 封裝為通用方法:可抽離 autoScrollToError 函數(shù),在多個(gè)表單中復(fù)用。

總結(jié)

長(zhǎng)表單 + 折疊面板是后臺(tái)系統(tǒng)的常見(jiàn)組合,但校驗(yàn)體驗(yàn)不能因此打折。通過(guò) 利用 DOM 結(jié)構(gòu)向上溯源 + 自定義 data 屬性,我們實(shí)現(xiàn)了 零配置、全自動(dòng)的錯(cuò)誤定位與面板展開(kāi),既優(yōu)雅又實(shí)用。

好的交互細(xì)節(jié),往往就藏在這些“用戶看不見(jiàn)但能感受到”的地方。

到此這篇關(guān)于Element UI長(zhǎng)表單校驗(yàn)失敗后自動(dòng)展開(kāi)折疊面板并滾動(dòng)定位的文章就介紹到這了,更多相關(guān)Element UI自動(dòng)展開(kāi)折疊面板滾動(dòng)定位內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

梁山县| 房产| 喀什市| 遂溪县| 横山县| 横峰县| 安达市| 长宁区| 乌拉特中旗| 仙桃市| 环江| 惠东县| 浦北县| 阿勒泰市| 达拉特旗| 厦门市| 林西县| 富阳市| 高州市| 金秀| 鸡东县| 宜城市| 高州市| 台山市| 武清区| 武陟县| 和平县| 隆德县| 天津市| 松江区| 河北省| 弥渡县| 达尔| 乌鲁木齐市| 象山县| 巍山| 慈溪市| 宜川县| 兴安县| 阳山县| 大邑县|