ちょっと悩んだところがあったのでメモ。
やりたいこと
Vue3でBootstrap5を使用し、Modalを実装する。
Vue3対応のBootstrapVueはまだ0.1.0(2021/12/18現在)なので使用しない。
単純なボタンクリック以外でもモーダルを非表示にしたいので、JavaScriptで非表示を制御したい。
諸々のバージョン
@popperjs/core@2.11.0
bootstrap@5.1.3
vue@3.2.22
実装方法
bootstrap.Modalのshow()
とhide()
を使用する。
https://getbootstrap.jp/docs/5.0/components/modal/#methods
非表示だけでなく、表示の方もJavaScriptで制御する。
悩んだところ
当初、モーダルの表示はdata-bs-toggle
とdata-bs-target
の属性を指定し、モーダルを非表示にする際にだけ上記のメソッドhide()
を使おうとしていたが、hide()
が機能しなかった。
原因
Bootstrapのドキュメントのこの部分について理解に誤りがあった。
var myModal = new bootstrap.Modal(document.getElementById('myModal'), options)
たとえばdata-bs-targetで実装したmyModal
を表示させた状態で、上記のようにModalのインスタンスを作成しても、その時点での表示の状態などはインスタンスのプロパティ内に反映されない。
具体的には、Modelのコンストラクタ内で、引数のエレメントに関係なく、__Shownというプロパティがfalseの状態で初期化される。
class Modal extends BaseComponent {
constructor(element, config) {
super(element, config)
this._dialog = SelectorEngine.findOne(SELECTOR_DIALOG, this._element)
this._backdrop = this._initializeBackDrop()
this._focustrap = this._initializeFocusTrap()
this._isShown = false
this._isTransitioning = false
this._scrollBar = new ScrollBarHelper()
}
__Shownがfalseの場合、hide()
は何もせずにreturnするような実装になっている。
hide() {
if (!this._isShown || this._isTransitioning) {
return;
}
(以下略)
なので、表示させるときもshow()
を使ってJavaScriptで表示させてやって、
非表示にするときはそのインスタンスに対してhide()
を呼び出すという実装が必要。
所感
結局こうやって自分でJavaScript書かなきゃいけない部分が増えていって最終的にごちゃごちゃしそう。