クモのようにコツコツと

フロントエンドエンジニア イイダリョウのブログ。略称「クモコツ」

【Vue.js】v-bindでclass名を動的に追加、削除する!(北斗の拳の名言編)

Vue.jsの続きです。前回まではJSONファイルの読み込みをしました。今回は属性値の動的な変更をします。v-bindを使ってclass名の追加、削除を行います。それではいきましょう!

【目次】

※前回:【Vue.js】axiosでJSONファイルを読み込む(はっぴいえんど編) - クモのようにコツコツと

v-bindは属性を指定するディレクティブ

以前の記事でv-onV-ifv-forをやってみた。これら(v-hoge)は「ディレクティブ」というVue.js独自の属性。

※参考:【Vue.js】イベント(v-on)、分岐(v-show、v-if)、ループ(v-for)をやってみた! - クモのようにコツコツと

今回は別のディレクティブでv-bindをやってみる。v-bindはタグの中の属性を指定するディレクティブ。

今回作ったもの

See the Pen Vue.js v-bind 04 by イイダリョウ (@i_ryo) on CodePen.

ここに至る道筋を書いていく。

v-bind:hrefでURLを指定

まずはv-bind:hrefをやってみた。URLを指定できた。

See the Pen Vue.js v-bind 01 by イイダリョウ (@i_ryo) on CodePen.

<h2>Vue.jsのv-bind</h2>
<div id="app">
  <p><a href="https://www.i-ryo.com/" target="_blank">URLを直接指定</a></p>
  <p><a v-bind:href="myUrl" target="_blank">URLをv-bindで指定</a></p>
</div>
  • #appの中にp要素が2つ
  • 一つ目のpにはhref属性に直接URLが書いてある
  • 二つ目のpにはv-bind:hrefmyUrlキーを指定

どちらもクリックするとリンクが開く。二つ目がなぜリンクが開くかというとJSでURLを指定している。

new Vue ({
    el: '#app',
    data:{
      myUrl: 'https://www.i-ryo.com/'
      }
})
  • Vueのインスタンス作成
  • elキーで#appを紐付け
  • dateキーの中に連想配列
  • 連想配列myUrlキーの値にURLが入っている

これでmyUrlにURLが紐付けられている。

でも、これだけだとあまり恩恵がわからない。href属性に直接URL書いた方が楽じゃん?という感想。

v-bind:syleでCSSスタイルを指定

次にv-bind:styleやってみた。CSSスタイルを指定する。

See the Pen Vue.js v-bind 02 by イイダリョウ (@i_ryo) on CodePen.

<h2 >Vue.jsのv-bind</h2>
<div id="app">
  <p class="blue">CSSでスタイル指定</p>
  <p v-bind:style="{color: myColor}">v-bindでスタイル指定</p>
</div>
  • #appの中にp要素が2つ
  • 一つ目のpにはclass名blueに対してCSSファイルにスタイルを書いている。
  • 二つ目のpにはv-bind:stylecolorプロパティの値をmyColorキーで指定
.blue {
  color: blue;
}

一つ目のpのCSSは文字色blue

二つ目のpはJSの中でCSSスタイルを指定。

new Vue ({
    el: '#app',
    data:{
      myColor: 'red'
      }
})
  • Vueのインスタンス作成
  • elキーで#appを紐付け
  • dateキーの中に連想配列
  • 連想配列myColorキーの値に値が入っている

うーむ、確かにスタイル効いた。効いたけれども!まだ恩恵がよくわからねぃ。。

CSSスタイルはCSSファイルに書いた方がメンテナンス上よろしいのではないだろうか??

期待してたのはこういうことじゃないんだよなー、なんつうか、動的に変化をさせたいというか。。

v-bind:classでclass名の追加、削除

と思いながら、引き続き調べていたら、やりたいことを実現している記事があった!

※参考:vue.js tips - v-bind:class を使って class の on/off を切り替えよう | phiary

ボタンを押すと文字の色が変わる。class名の追加、削除を交互に繰り返す動き!作ってみた。

See the Pen Vue.js v-bind 03 by イイダリョウ (@i_ryo) on CodePen.

そう、これこれ!jQueryでよくやってたaddClass()とかtoggleClass()みたいな動き!これがやりたかった。

HTMLはこちら

  <div id="app">
    <div class="btn">
      <button v-on:click='active01=!active01' v-bind:class='{active:active01}'>押して!</button>
    </div>
  </div>
  • #appの中に.btn、その中にbutton要素
  • buttonの属性v-on:clickでクリックするとactive01の値が!によってon(true)とoff(false)が切り替わる(反対になる)
  • buttonの属性v-bind:class でclass名activeactive01キーの値がon(true)になると追加される

.activeのCSSはこちら

.btn .active {
  color: yellow;
  background-color: #000;
}

文字色は黄色、背景は黒だが、ページロードの時点ではまだこのclassは当たっていない。ボタンを押すとclassが当たる。その動きはJSで指定している。

JSはこちら

new Vue ({
    el: '#app',
    data: {
        active01: false
    }
})
  • Vueのインスタンス作成
  • elキーで#appを紐付け
  • dateキーの中に連想配列
  • 連想配列active01キーの値false

これでページロード時はactive01falseでclassが当たらない。ボタンを押すとfalsetrueが切り替わるため、class名の追加、削除を繰り返す。

うむ、スタイルはCSSファイルに書いて、JSはクリックイベントv-on:clickとclass名の紐づけv-bind:classという切り替えスイッチの役割になった。

複数ボタンで「北斗の名言」を表示する

もう少し改造してみる。ボタンの数を増やして、ボタンクリックによってclassを当てる先も2箇所に増やしてみた。

See the Pen Vue.js v-bind 04 by イイダリョウ (@i_ryo) on CodePen.

各ボタンをクリックすると、ボタンの文字色が変わると同時にそのキャラの名言が現れる。

HTMLはこちら

  <div id="app">
    <div class="btn">
      <button class="name" v-on:click='active01=!active01' v-bind:class='{active:active01}'>ラオウ</button>
      <button class="name" v-on:click='active02=!active02' v-bind:class='{active:active02}'>トキ</button>
      <button class="name" v-on:click='active03=!active03' v-bind:class='{active:active03}'>ジャギ</button>
      <button class="name" v-on:click='active04=!active04' v-bind:class='{active:active04}'>ケンシロウ</button>
       <button class="name" v-on:click='active05=!active05' v-bind:class='{active:active05}'>モヒカン</button>
    </div>

  <ul class="text">
    <li class="serif" v-bind:class='{active:active01}'>
      ラオウ「我が人生、一片の悔いなし!」</li>
    <li class="serif" v-bind:class='{active:active02}'>
      トキ「愛するがゆえに見守る愛もある」</li>
    <li class="serif" v-bind:class='{active:active03}'>
      ジャギ「俺の名前を言ってみろ!」</li>
    <li class="serif" v-bind:class='{active:active04}'>
      ケンシロウ「お前はもう、死んでいる」</li>
    <li class="serif" v-bind:class='{active:active05}'>
      モヒカン「あべし!」</li>
  </ul>
  </div>
  • #appの中にdiv要素(.btn)とul要素(.text
  • .btnの中にbuttonが5つ
  • buttonの属性は先ほどと同じv-on:clickv-bind:classだが、キー名に固有の番号が振ってある
  • .textの中にli要素(. serif)が5つ
  • . serifの属性はv-bind:classで、キーにbuttonと同じ固有の番号が振ってある。

CSSの設定

.serif {
  display: none;
}

.btn .active {
  color: red;
}

/*中略*/

.text .active {
  display: block;
}
  • .serifの初期は非表示
  • .btnの中の.activeの文字色は赤(初期は当たっていない)
  • . textの中の.activeを表示に(初期は当たっていない)

初期は.activeがないのでボタンの文字色赤や名言の表示のCSSが当たっていない。ボタンをクリックすると.activeの追加、削除が交互に繰り返す。その設定はJSにある。

new Vue ({
    el: '#app',
    data:{
        active01: false,
        active02: false,
        active03: false,
        active04: false,
        active05: false
    }
})
  • Vueのインスタンス作成
  • elキーで#appを紐付け
  • dateキーの中に連想配列
  • 連想配列の中active01active05キーの値は全てfalse

一つのクリックで複数箇所にclass名を追加できたのでもう少し凝ったこともできそう!

最後に

f:id:idr_zz:20190529215721j:plain

ということで、最初はいまいち使い道がわからなかったv-bindですがv-onのクリックイベントと組み合わせるといろいろなことができることがわかりました!

次回は同じくディレクティブのv-modelを使ってユーザーの入力操作による動的なページ変更をやってみたく。ここらへんからようやくJSフレームワークっぽい領域に入っていくのでせうか?それではまた!!