Vue.jsとBootstrapを組み合わせて、BootstrapのトーストをVue.jsから使えるようにする方法を紹介します。
なお、今回はBootstrapVueではなく、通常のBootstrap5をVue.js(CDN)と組み合わせて使用する方法を紹介します。BootstrapVueのほうがコーディングはかんたんですが、導入のしやすさという観点から素のBootstrapとVue.jsを組み合わせたいケースも多いでしょう。今回はそういったケースを想定して、解説していきます。
なお、あらかじめBootstrapのトーストの使い方を確認しておいていただけると理解がスムーズかと思います。Bootstrapのトーストに慣れていない方ははじめにこちらをご覧いただくことをおすすめします。
Vue.jsからトーストを使えるようにするには?
はじめに今回作っていくサンプルの完成品を載せておきます。
ボタンをクリックするとトーストが表示されます。トーストの表示内容やクリックイベントの処理は、すべてVue.jsでコントロールしています。
Vue.jsからトーストを呼び出したいときも、Vue.jsなしでの場合と基本的な流れは同じです。
はじめにトーストを初期化しておき、初期化で得られたインスタンス(オブジェクト)をどこかの変数に置いておきます。あとはトーストを表示させたいタイミングで、その変数に含まれるメソッド(.show()
や.hide()
)を呼び出せばOKです。
Vue.jsと組み合わせるに当たり変わるポイントはひとつだけで、トーストのインスタンスをdataプロパティに置いておくようにするだけです。
data:{
toast: {
el: null,//初期化して得られたインスタンスをdataに置いておく
}
}
こうすることで、Vue.js内のどこからでもトーストのインスタンスにアクセスできるようになり、任意のタイミングでトーストを表示させることができます。
なお、サンプルのようにトーストに関わるデータはまとめておくと、読みやすさが向上します。トーストに表示するタイトルや本文といったデータもdataにまとめて配置しておくとよいでしょう。
data:{
toast: {
title: "",//タイトル
body: "",//本文
color: "#aaa",//カラー
el: null,//トーストのインスタンス
}
}
もちろんトースト本体のHTMLもVue.jsのマウント要素内(#appの中)に置いておくようにします。
<div id="app">
//トースト本体のHTMLも#appの中に置いておく
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
・・・
</div>
</div>
サンプルを作ってみよう!
全体的な流れがわかったところで、サンプルを作っていきましょう。
STEP1 Vue.jsとBootstrapを導入する
まず、Vue.jsとBootstrapを導入します。Bootstrapの公式サイトからスターターテンプレートをコピーして貼り付けます。
さらにVue.jsをCDNで導入します。body終了タグの直前に次の1行を貼り付けましょう。
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
bodyタグ直下にdiv要素をつくり、idをappとします。
<body>
<div class="container" id="app">
</div>
...
Vue.jsのコードを作成し、作成したdivをマウントします。全体としてはこんな感じです。
<!doctype html>
<html lang="ja">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<title>トーストのサンプル(Vue.js)</title>
</head>
<body>
<div class="container" id="app">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM"
crossorigin="anonymous"></script>
<script>
var app = new Vue({
el: "#app",
data: {
},
mounted() {
},
methods: {
}
})
</script>
</body>
</html>
これでBoostrapとVue.jsを使用する準備ができました。
STEP2 トーストをつくる
次にトーストの雛形を作ります。
ここでは上の画像のようなトーストを作っていきます。
とはいえ、こちらもBootstrap公式のサンプルをそのまま使うのがおすすめです。タイトルなどプログラムから変えたい部分はマスタッシュ{{}}
でデータを差し込めるようにしておきます。
<div class="toast" role="alert" aria-live="assertive" aria-atomic="true">
<div class="toast-header">
<svg class="bd-placeholder-img rounded me-2" width="20" height="20"
xmlns="http://www.w3.org/2000/svg" aria-hidden="true" preserveAspectRatio="xMidYMid slice"
focusable="false">
<rect width="100%" height="100%" :fill="toast.color"></rect>
</svg>
<strong class="me-auto">{{toast.title}}</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="閉じる"></button>
</div>
<div class="toast-body">
<div v-html="toast.body"></div>
</div>
</div>
今回はタイトルと本文、左上の■のカラーをデータバインディングで変更できるようにしてみました。データバインディングする変数をdata内に用意します。
<script>
var app = new Vue({
el: "#app",
data: {
// トーストのデータ
toast: {
title: "",
body: "",
color: "#aaa",
el: null,
}
},
ここで定義したデータがトースト内の{{}}に自動的に反映されます。イメージがつかめない方は、一度Vue.jsの基本を確認してみるといいでしょう。
STEP3 トーストを初期化する
以前の記事でも紹介しましたが、Bootstrapのトーストは初期化を行わないと使用できません。
トーストを配置しただけでは動作しませんので、必ず初期化を行う必要があります。初期化をすることでトーストのインスタンスが生成され、プログラムからトーストを呼び出せるようになります。
Vue.jsのmountedイベントサイクルを使い、マウントが完了した時点でトーストを初期化するようにします。
mounted() {
// トーストの初期化
this.toastInit();
},
methods: {
// トーストを初期化する
toastInit() {
var toastElList = [].slice.call(document.querySelectorAll(".toast"));
this.toast.el = toastElList.map(function (toastEl) {
return new bootstrap.Toast(toastEl, {
delay: 5000,
});
});
},
トーストを初期化する関数toastInitを作成し、mountedイベントで呼び出すようにしてみました。
初期化するコードはBootstrapのトーストの解説ページに記載されているままです。取得されたインスタンスは先述の通りdataに保存しておきます。
STEP4 ボタンでトーストを呼び出せるようにする
ここまでくれば、あとは作ったトースト呼び出すだけです。
ボタンを用意し、クリックされたらトーストが表示されるようにしてみましょう。
まず、トーストを呼び出す関数を作成します。
// トーストを表示する
showToast() {
this.toast.title = "タイトル";
this.toast.body = "トーストが表示されました~!";
this.toast.color = "#007aff";
this.toast.el[0].show();
}
トーストのインスタンスに含まれるshowメソッドを呼び出すと、トーストが表示されます。
ボタンにshowToastメソッドをクリックイベントとして設定します。
<button @click="showToast"></button>
これでボタンがクリックされるとshowToastが呼ばれ、トーストが表示されるようになりました。
実際に動かしてみましょう。きちんとトーストが表示されると思います。
まとめ
いかがでしたか。意外とかんたんですよね。
Vue.jsと組み合わせるときでも、インスタンスをdataに配置しておく以外は、Bootstrap公式のサンプルの通りやればOKです。
AjaxによるUI制作が増えつつある昨今では、ページ遷移することなくユーザーに通知することができるトーストのニーズが増えつつあります。Bootstrapならトーストもかんたんに実装できますので、これまで触れたことがなかった方は、ぜひお試しください。
コメント