ElementUIのel-selectコンポーネントで動的に無効状態を設定した際の高さ変更問題の解決策

課題の概要

Vue2プロジェクトにおいて、el-selectコンポーネントを使用中に`disabled`プロパティを動的に`true`に変更すると、要素の高さが変化する現象が発生しました。

根本原因の分析

ブラウザの開発者ツールを使用して調査した結果、コンポーネント内部の`input`要素に対して`height`スタイルが動的に適用されていることが判明しました。

プロジェクト内のコードを確認してもこの設定をトリガーするロジックは見当たらず、コンポーネント自体の内部処理である可能性が高いと推測されました。

ElSelectのソースコード(`node_modules\element-ui\packages\select\src\select.vue`)を確認したところ、実際に`height`を設定するメソッドが存在することが確認できました:

adjustInputHeight() {
  if (this.collapseTags && !this.filterable) return;
  this.$nextTick(() => {
    if (!this.$refs.reference) return;
    let inputElements = this.$refs.reference.$el.children;
    let targetInput = Array.from(inputElements).find(item => item.tagName === 'INPUT');
    const tagContainer = this.$refs.tags;
    const tagHeight = tagContainer ? Math.round(tagContainer.getBoundingClientRect().height) : 0;
    const baseHeight = this.defaultInputHeight || 40;
    // 高さ計算ロジック
    targetInput.style.height = this.selectedOptions.length === 0
      ? baseHeight + 'px'
      : Math.max(
        tagContainer ? (tagHeight + (tagHeight > baseHeight ? 6 : 0)) : 0,
        baseHeight
      ) + 'px';
    if (this.isOpen && this.placeholderText !== false) {
      this.broadcast('ElSelectDropdown', 'refreshPopper');
    }
  });
}

このメソッドは`disabled`状態の変更時に呼び出されます:

watch: {
  componentDisabled() {
    this.$nextTick(() => {
      this.adjustInputHeight();
    });
  },
  // ...

対応策の実装

このロジックは主に複数選択時のテキストフィールド高さ調整のために存在するものと考えられます。単一選択モードでは高さ変更の必要がないため、監視コールバックを置き換えることで問題を解決しました。

import Vue from 'vue'
import ElementUI from 'element-ui'

const originalDisabledWatcher = ElementUI.components.Select.watch.componentDisabled
ElementUI.components.Select.watch.componentDisabled = function () {
  if (this.allowsMultiple) {
    originalDisabledWatcher.call(this)
  }
}

Vue.use(ElementUI)

タグ: ElementUI vuejs select-component dynamic-disabling height-calculation

7月2日 17:37 投稿