MeWrite Docs

Alpine.js: x-bind:classがクラスを削除する

Alpine.jsでx-bind:classを使用した際に意図しないクラス削除が発生する問題

概要

Alpine.jsのx-bind:classで複数の条件付きクラスを設定する際、同じクラスが複数の条件に含まれていると、falseの条件によってクラスが削除されてしまう問題です。

エラーメッセージ

エラーメッセージは表示されませんが、期待したクラスが適用されない現象が発生します。

1
2
3
4
5
6
<!-- 期待: redとtext-yellowが適用される -->
<!-- 実際: redが削除される -->
<button x-bind:class="{
  'red text-yellow': open,
  'red text-blue': !open && level === 12
}">Button</button>

原因

  1. クラスの上書き処理: Alpine.jsはオブジェクトのキーを順番に処理し、後の条件がfalseの場合、そのキーに含まれるクラスを削除する
  2. 複数キーでの同一クラス: 同じクラスが複数のキーに存在すると、最後に評価された条件が優先される
  3. オブジェクトの評価順序: JavaScriptオブジェクトのキー順序に依存した動作

解決策

1. クラスを分離して定義

1
2
3
4
5
<button x-bind:class="{
  'red': open || (!open && level === 12),
  'text-yellow': open,
  'text-blue': !open && level === 12
}">Button</button>

2. 配列構文を使用

1
2
3
4
<button x-bind:class="[
  open ? 'red text-yellow' : '',
  !open && level === 12 ? 'red text-blue' : ''
]">Button</button>

3. computedプロパティを使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<div x-data="{
  open: true,
  level: 32,
  get buttonClass() {
    if (this.open) return 'red text-yellow';
    if (this.level === 12) return 'red text-blue';
    return '';
  }
}">
  <button x-bind:class="buttonClass">Button</button>
</div>

4. 三項演算子で明示的に

1
2
3
4
5
<button x-bind:class="open
  ? 'red text-yellow'
  : (level === 12 ? 'red text-blue' : '')">
  Button
</button>

5. ベースクラスを静的に定義

1
2
3
4
<button class="red" x-bind:class="{
  'text-yellow': open,
  'text-blue': !open && level === 12
}">Button</button>

6. 関数で動的に生成

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<div x-data="{
  open: true,
  level: 32,
  getClasses() {
    const classes = [];
    if (this.open) {
      classes.push('red', 'text-yellow');
    } else if (this.level === 12) {
      classes.push('red', 'text-blue');
    }
    return classes.join(' ');
  }
}">
  <button x-bind:class="getClasses()">Button</button>
</div>

よくある間違い

  • 複数の条件で同じクラス名を使用する
  • 条件の評価順序を考慮しない
  • 静的クラスと動的クラスを混在させる際にx-bind:classで上書きしてしまう

関連エラー

参考リンク

最終更新: 2025-12-13