Vue.jsでBootStrapをつまみ食い的に使う


概要

Vue.jsのVue CLIからBootStrapを使う方法。

「BootStrapを使おう!さぁ先ずは基本を学ぼう」と構えて臨むのではなく、「このデータ構造の表現にちょうどよいUI無いかな? お、BootStrapのxxのコンポーネントが良さ気じゃん」と気軽につまみ食いで使う、ことを目指すとする。

サンプルに用いるデータ構造

次のような配列データを、Vue.jsを用いたUIで表現する場合を考える。
表示対象は「datetime, type, notes」の3つとする。

activitylist = [
    {
        id: 5,
        datetime: "1596229200",
        type: 1,
        notes: '翌日の6時に起きたとする'
    },{
        id: 4,
        datetime: "1596223800",
        type: 1,
        notes: '翌日の4時半に目が覚めたとする'
    },{
        id: 3,
        datetime: "1596201000",
        type: 0,
        notes: '2020-07-31 22:10、つまり夜22時過ぎに寝た場合を仮定'
    },{
        id: 2,
        datetime: "1596164400",
        type: 2,
        notes: '薬を昼12時に飲んだとする。'
    }
];

typeに指定された値に対して、その値を配列番号と見なして、それぞれ配列要素のtitleキーに設定した文字列に置き換えて表示する、ものとする。

typelist = [
    { 
        title: '寝た'
    }, {
        title: '起きた'
    }, {
        title: '服薬'
    }
];

これらの配列データをViewListCard.vueで定義し、
コンポーネントItemCard.vueに配列をPropsで渡して、
表示の仕方はコンポーネントItemCard.vueに任せる、
という設計を仮定する。

具体的なサンプルコードは次のようになる。

  • ./src/components/ViewListCard.vue
  • ./src/components/ItemCard.vue
    • ItemCard0.vueItemCard3.vue がそれぞれの段階ごとのサンプルコード

テキストをマスタッシュ構文でそのまま表示する

上述の配列データactivitylistの各要素の3項目を、次の変換のみを行って
マスタッシュ(Mustache)を用いてテキストで表示すると
次のようになる。

  • datetime: UNIX時間(秒)を「YYYY-MM-DD . HH:MM:00」の文字列に変換する
  • typeを、typelistの配列番号に応じた要素のtitleキーに設定された文字列に変換する
  • notesはそのまま表示する。

▼card0.png

本サンプルでは、それぞれのカード(様の部分)をタップすると編集モードになるる、という設計とする。その編集モードは、先ずはHTML標準のinputタグを用いて実装すれば、次のような表示となる。

▼card0-edit.png

ここまでのサンプルコードは次のようになる。
ItemCard0.vue を、実際にはItemCard.vueとして動作させる。

以下、上述までの表示形式を、BootStrapを用いていい感じにする方法を述べる。

BootStrap(BootStrapVue)を使う準備をする

Vue.js上でBootStrapを利用するには、BootStrapVueを用いるのが簡単。

BootstrapVue provides one of the most comprehensive
implementations of Bootstrap v4 for Vue.js.

Vue CLIのプロジェクトのルートフォルダにて、以下のコマンドでインストールする。

npm install bootstrap-vue    --save

続いて、ルートにあるmain.jsを開いて、次の2行(本サンプルではコメント含めて4行)を追加する。

main.js
import Vue from 'vue'
import App from './App.vue'

// +++ add for bootstrap +++
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
// -------------------------

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

以上で、BootStrapをVue CLI上で使う準備は完了。

ref. https://bootstrap-vue.org/docs

項目のタイトル相当を見やすくしたい

先ほどの「card0.png」の画面を見やすくすることを考える。

「起きた」や「寝た」などの表示を上手く装飾するものがないか?
と公式BootStrapVueのComponentのページを見ていく。

このページは、簡単な説明を一覧出来て、それぞれのComponentの説明ページに飛ぶとサンプル表示もあるので、「そのComponentによる装飾がどういうものか?」を掴みやすくて、助かる。

どんなコンポーネントがあるか?を上から順に見ていく中で、
今回のケースなら「バッジ(Badge)」で「起きた」「寝た」などを表示するのがよさそうだ、などのように装飾の仕方を決める。

本サンプルでは、上述のBadgeによる装飾とnotesの値をReadOnlyのForm Textareaで表示するものとする。
この場合は、次のような表示になる。

▼card1.png

上記を実装するには、コンポーネントItemCard.vueに対して、次のような変更を加える。

  • {{typeStr}}としていた部分を、<b-badge v-bind:variant="typeVariant">{{typeStr}}</b-badge>とする
  • {{notesCurrent}}としていた部分を、<b-form-textarea v-bind:value="notesCurrent" readonly rows="2" max-rows="2"></b-form-textarea>とする
  • 利用するコンポーネントを「import { BBadge, BFormTextarea } from 'bootstrap-vue'」で読み込んで、「components: {}」に指定する

たったこれだけのコード修正で、で上図(card1.png)の様な見やすい表示に変更できる。BootStrapはとても簡単で使いやすい。

なお、編集モード(card0-edit.png)の表示については、notesCurrentの部分は、Form Textareaを用いてreadonly属性を外せばよいだろう。編集モード側のUI変更を含めたサンプルコードは以下。

編集モード側の表示は以下のようになる。

▼card1-edit.png

なお、<b-badge>コンポーネントはvariant属性でカラーリングを変更できる。サンプルコードでは、typelist配列の各要素に、variantキーを追加し、それに従ったBadgeカラーを表示する実装にしてある。

[
    { 
        title: '寝た',
        variant: 'primary'
    }, {
        title: '起きた',
        variant: 'secondary'
    }, {
        title: '服薬',
        variant: 'success'
    }
]

variant属性への指定において、デフォルトで利用可能な値は以下を参照。

編集モードで選択項目をラジオボタンで、ついでに確定ボタンもいい感じに装飾する

続いて、上図の編集モード(card0-edit.png)における「起きた」「ネタ」をラジオボタンで選べるようにする。HTML標準の<input type="radio">でも良いのだが、BootStrapにForm Radioコンポーネントがあるので、これを使う。

次の公式ガイドに従って、<b-form-group><b-form-radio-group>を用いる。

編集対象は(propsで渡されたtypeをもとに生成した)typeCurrentなので、これをv-model属性で<b-form-radio-group>にバインドする。

<b-form-group label="記録の種別を選んでください">
    <b-form-radio-group
        v-model="typeCurrent"
        :options="typeOptions"
    ></b-form-radio-group>
</b-form-group>

選択肢は、v-bind:options属性(略記して:options属性)で設定する。設定すべき変数のフォーマットは配列で、各要素は次の2つのキーを持つ。

  • 選択肢の文字列としてtext
  • 選択されたときに編集対象(=v-modelでバインドされた変数)へ代入する値としてvalue

したがって、本サンプルでは(propsで渡された)typelistを元にして次のようにtypeOptins配列を生成しておく。

this.typelist.forEach((elem, index)=> {
    this.typeOptions.push({
        text: elem.title,
        value: String(index)
    })
})

ついでなので、「確定」ボタンもBootStrapVueが提供するButtonコンポーネントで装飾する。これは、「<button @click="clickBtnEditFinish">確定</button>」としていたところを、「<b-button @click="clickBtnEditFinish">確定</b-button>」と置き換えるだけで良い。

以上の変更を加えたコンポーネントItemCard.vueのコード全体は以下となる(※importcomponentsへの追加も忘れずに→リンク先のコードを参照)。

上記のコードへの変更によって、編集モードの表示は次のように変わる。

▼card2-edit.png

日時の編集ボックスを、いい感じに装飾する

最後に、上図(card2-edit.png)の日付と時刻の入力を良い感じに装飾する。

(※HTML5利用可能環境であれば、素のHTML inputタグが実装している入力支援のpickerを利用可能なので、BootStrap版に置き換えるか否かは好みの問題かもしれない。一応、IEとPC版SafariはHTML5に未対応のため同じ表示にならないが、BootStrap版なら同じ表示が可能、という差はある)

これまでと同様にBootStrapVueのコンポーネント一覧から、日付と時刻のPickerを探す。

Form DatepickerForm Timepickerがあるので、これを使う。

使い方は、それぞれを次のように置き換えるだけ。

置き換え前:

<input v-model="dateCurrent" type="date">
<input v-model="timeCurrent" type="time">

置き換え後:

<b-form-datepicker v-model="dateCurrent" class="mb-2"></b-form-datepicker>
<b-form-timepicker v-model="timeCurrent" locale="ja"></b-form-timepicker>

置き換え後のサンプルコードは次のようになる。

※ここで「class=mb-2」を指定しているが、これはBootStrap v4.5で定義されているclassのこと。BootStrapVueでは、BootStrapで準備されているClassをそのまま利用できる。

上記のコードへの変更によって、編集モードの表示は次のように変わる。

▼card3-1edit.png

▼card3-2date.png

▼card3-3time.png

なお、「Picker経由だけでなく、時刻を直にテキストとして入力もしたい」という場合は、inputタグを組わせることで実現できる。BootStrapVueでの、その実装例も公式サイトの以下に記載がある。とても親切♪

以上ー。