MENU

【Javascript】Vue3のディレクティブまとめ

ディレクティブとは?

ディレクティブは、HTML要素(DOM要素)に追加の動作を追加するVue.jsの独自の属性です。
Vueの組み込みディレクティブを使用して、フォーム、リスト、スタイルやユーザーに表示される内容を操作・管理することができます。

Vue3のディレクティブの分類

分類 ディレクティブ 説明
データバインド(表示)系 v-text,v-bind,v-html,v-onceなど データをページに反映・表示
イベント系 v-on イベント処理を実行
フォーム(データのやり取り)系 v-model フォームからの入力を取得
制御系 v-if,v-forなど 条件分岐や繰り返し処理を実行

データバインドとは?

bind(バインド)・・・(…を)結び合わせる、結びつける。の意味。
データ バインディングとは、アプリ側の UI と、そこに表示されるデータを同期(接続)する処理です。 バインドが適切に設定され、データから適切な通知が提供される場合、データの値が変更されると、そのデータにバインドされている要素に変更が自動的に反映されます。

Vue3のディレクティブまとめ

v-text

v-textは、要素内にコンテンツをバインド(表示)します。
既にコンテンツが挿入されている場合は上書きとなります。

HTML

<div id="app">
  <!-- 以下2つは同じ意味。表現が異なるだけ -->
  <p v-text="message">既存のコメント</p>
  <p>{{ message }}</p>
</div>

JS

<script>
  Vue.createApp({
    data(){
      return {
        message: 'Hello Vue js!'
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Untitled
by nanimonai (@nanimonaikedo)
on CodePen.

v-bind

htmlタグの属性に対してv-textの{{…}}だけでは利用できません。
属性値の操作にはv-bindを使用します。
:のみと省略することもできますが、はじめのうちはv-bindを記述しておくことがおすすめです。

HTML

<div id="app">
  <p><a v-bind:href="url" target="_blank">google</a></p>
  <!-- 省略形 -->
  <p><a :href="url" target="_blank">google</a></p>
  <!-- これでは動かない -->
  <p><a href="{{url}}" target="_blank">google</a></p>
</div>

JS

<script>
  Vue.createApp({
    data(){
      return {
        url: 'https://www.google.com'
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Untitled
by nanimonai (@nanimonaikedo)
on CodePen.

v-html

v-htmlは、{{ … }}の中身をテキストではなくhtmlとして出力します。

HTML

<div id="app">
  <p>v-text: <span v-text="htmlText"></span></p>
  <p>v-html: <span v-html="htmlText"></span></p>
</div>

JS

<script>
  Vue.createApp({
    data(){
      return {
        htmlText: '<span style="color: red;">RED</span>'
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Untitled
by nanimonai (@nanimonaikedo)
on CodePen.

v-pre

v-preは、要素内のvueコードをテキストとしてそのまま表示します。

HTML

<div id="app">
  <p v-pre>{{ message }}</p>
  <p>{{ message }}</p>
</div>

JS

<script>
  Vue.createApp({
    data(){
      return {
        message: 'Hello Vue js!'
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Vue3 v-pre
by nanimonai (@nanimonaikedo)
on CodePen.

v-once

v-onceは、一度目だけ変数が変更した場合に更新を行います。
2回目以降は変数が変更しても更新されません。

HTML

<div id="app">
  <form v-on:submit.prevent>
    <label for="textBox">テキスト: </label>
    <input type="text" id="textBox" v-model="text">
  </form>
  <div v-once>再描画なし: {{text}}</div>
  <div>再描画あり: {{text}}</div>
</div>

JS

<script>
  Vue.createApp({
    data(){
      return {
        text: '初期値'
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Untitled
by nanimonai (@nanimonaikedo)
on CodePen.

v-on

v-onは主に、マウス動作時などイベント発生時のJavaScriptの実行を関連付けられます。@と省略することもできますが、はじめのうちはv-onを記述しておくことがおすすめです。

HTML

<div id="app">
  <button v-on:click="countUp(2)">Add</button>
  <!-- 省略形 -->
  <button @click="countDown(2)">Remove</button>
  <p>Clicked {{ count }} times.</p>
</div>

JS

<script>
  Vue.createApp({
    data() {
      return {
        count:0 //初期値
      }
    },
    methods:{
      countUp(num){
        this.count += num
      },
      countDown(num){
        this.count -= num
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Count num
by nanimonai (@nanimonaikedo)
on CodePen.

利用できる主なイベント

分類 イベント名 説明
フォーム focus 要素にフォーカスが入ったとき
blur 要素からフォーカスが外れたとき
change 要素の値を変更したとき(input,select,textareaなど)
select テキストボックス/テキストエリアのテキストを選択したとき
submit フォームから送信したとき
マウス操作 click 要素をクリックしたとき
dbclick 要素をダブルクリックしたとき
mousedown マウスのボタンを押したとき※クリックとは異なる
mouseenter 要素エリアにマウスポインターが入ったとき
mouseleave 要素エリアからマウスポインターが外れたとき
mouseover 要素エリアにマウスオーバーしたとき
mouseout 要素エリアからマウスアウトしたとき
mousemove 要素の中をマウスポインターが移動したとき
mouseup マウスのボタンを離したとき ※mousedownとmouseupの一連の動きがclickと同等
キー操作 keydouwn キーを押したとき
keyup キーを離したとき
keypress キーを押し続けているとき
その他 resize ウィンドウサイズが変更したとき
scroll スクロールしたとき
error ページ内エラーが発生したとき
contextmenu コンテキストメニューを表示するまえ

v-model

v-modelは、formのinput要素やtextarea要素、select要素と双方向のデータバインディングを行います。
自動的に入力要素の更新が可能です。
value, checkedやselected属性の初期値は無視されるので注意が必要です。

入力ボックスのサンプル

HTML

<div id="app">
  <input type="text" v-model="message">
  <p>入力内容 : {{ message }}</p>
</div>

JS

<script>
  Vue.createApp({
    data() {
      return {
        message: 'Hello Vue!'
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Vue3 v-model
by nanimonai (@nanimonaikedo)
on CodePen.

チェックボックスのサンプル

HTML

<div id="app">
  <form action="">
    <div>OSを選んでください。</div>
    <input type="checkbox" id="windows" value="Windows" v-model="os">
    <label for="windows">Windows</label>
    <input type="checkbox" id="linux" value="Linux" v-model="os">
    <label for="linux">Linux</label>
    <input type="checkbox" id="mac" value="MacOS" v-model="os">
    <label for="mac">MacOS</label>
  </form>
  <p>選択:{{ os }}</p>
</div>

JS

<script>
  Vue.createApp({
    data() {
      return {
        os: []
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Vue3 v-model checkbox
by nanimonai (@nanimonaikedo)
on CodePen.

v-slot

v-slotは呼び出し元のコンテンツを呼び出し先テンプレートに埋め込むことが出来ます。

HTML

<div id="app">
  <hello-tpl>山田</hello-tpl>
</div>

JS

<script>
  Vue.createApp({})
  .component('hello-tpl', {
    template:`<div>こんにちは<slot>ゲスト</slot>さん!</div>`, 
  })
  .mount('#app')
</script>

スロットはテンプレート内に<slot>要素を埋め込みます。
これによって呼び出し側のコンテンツが、<slot>要素の合った場所に表示されます。

DEMO

See the Pen
Vue3 v-slot
by nanimonai (@nanimonaikedo)
on CodePen.


イメージ

 

v-if, v-else, v-else-if

v-ifディレクティブは、ブロックを条件に応じて表示したい時に使用されます。
v-else-ifとv-else要素は、それぞれv-if要素あるいはv-else-if要素の直後に書く必要があります。

HTML

<div id="app">
  <p v-if="flag">
    これはTrueの状態です。
  </p>
  <p v-else>
    これはFalseの状態です。
  </p>
  <button v-on:click="chaneFlag()">ボタンを押してね。</button>
</div>

JS

<script>
  Vue.createApp({
    data() {
      return {
        flag: true
      }
    },
    methods:{
      chaneFlag:function(){
        this.flag = !this.flag
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Vue3 v-if,v-else-if,v-else
by nanimonai (@nanimonaikedo)
on CodePen.

v-show

v-showは、式の値の真偽に基づいて、要素の表示・非表示をトグルします。
v-ifでは要素自体をDOMに表示しないのに対し、v-showではdisplay:none;で非表示にします。
処理速度はv-showの方が早く、繰り返し処理のv-forとv-ifの組み合わせは推奨されないので、複数のトグル要素を使用するときは、v-showを使用します。

HTML

<div id="app">
  <p v-show="flag">
    こんにちは!
  </p>
  <button v-on:click="chaneFlag()">ボタンを押してね。</button>
</div>

JS

<script>
  Vue.createApp({
    data() {
      return {
        flag: true
      }
    },
    methods:{
      chaneFlag:function(){
        this.flag = !this.flag
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Untitled
by nanimonai (@nanimonaikedo)
on CodePen.

v-for

v-forは配列やオブジェクトから順番に要素を取り出します。JavaScriptのforに当たります。

HTML

<div id="app">
  <ul>
    <li v-for="(item, index) in items" :key="item.title">
      {{index}} : {{item.title}} : {{item.author}} : {{item.published}}
    </li>
  </ul>
  <hr>
  <ul>
    <li v-for="(value, key, index) in books">
      {{index}} : {{key}} : {{value}}
    </li>
  </ul>
</div>

JS

<script>
  Vue.createApp({
    data() {
      return {
        items:[
          {title:'Romeo and Juliet ', author:'William Shakespeare', published:'1595'},
          {title:'Hamlet', author:'William Shakespeare', published:'1601'},
          {title:'Macbeth', author:'William Shakespeare', published:'1606'},
        ],
        books:{
          title:'Hamlet',
          author:'William Shakespeare',
          published:'1601',
        }
      }
    },
  }).mount('#app')
</script>

DEMO

See the Pen
Vue3 v-for
by nanimonai (@nanimonaikedo)
on CodePen.

v-memo

v-memoは、指定した値が最後のレンダリング結果と同じであれば、再レンダリング(更新)をスキップします。膨大なリストの中で変更があったDOMのみ更新させることで、パフォーマンスを最適化するのが目的です。
最適化の効果は1000件を超えるリストなどの描画の時に有効とあるので、大規模なデータを扱わない限りは使わなそうです。

HTML

<div id="app">
  <select v-model="selectedItem" v-on:change="selectItem">
    <option 
      v-for="item in items"
      v-bind:key="item.id" 
      v-bind:value="item.id"
    >
      {{ item.name }}
    </option>
  </select>
  <div v-for="item in items" :key="item.id" v-memo="[item.id, selectedItem]">
    <p v-if="item.id === selectedItem">{{item.name}} : selected ← ここだけ更新</p>
    <p v-else-if="item.id === preselectedItem">{{item.name}} : unselect ← ここだけ更新</p>
    <p v-else="item.id === selectedItem">{{item.name}} : unselect ← 更新しない</p>
  </div>
</div>

JS

<script>
  Vue.createApp({
    data() {
      return {
        items:[
          { id: 1, name:'ITEM1' },
          { id: 2, name:'ITEM2' },
          { id: 3, name:'ITEM3' },
          { id: 4, name:'ITEM4' },
          { id: 5, name:'ITEM5' },
          { id: 6, name:'ITEM6' },
          { id: 7, name:'ITEM7' },
          { id: 8, name:'ITEM8' },
          { id: 9, name:'ITEM9' },
        ],
        selectedItem:1,
        preselectedItem:1,
      }
    },
    methods:{
      selectItem:function(e){
        this.preselectedItem = this.selectedItem
      }
    }
  }).mount('#app')
</script>

DEMO

See the Pen
Untitled
by nanimonai (@nanimonaikedo)
on CodePen.

v-cloak

v-cloakはアクセス時のマスタッシュ(ダブルカーリーブレイス)を表示させないように設定することができます。
ブラウザでindex.htmlファイルを開くと一瞬画面上に{{ … }}が表示されてしまいます。
表示されるのは非常に短い時間のでどのようなものが表示されるかまでわからない場合もあります。

v-cloakなし

HTML

<div id="app">
  <p>{{ message }}</p>
</div>

CSS

[v-cloak] {
  display: none;
}

JS

<script>
  // v-cloak確認のためvueの実行を遅らせる
  window.setTimeout(() => {
    Vue.createApp({
      data() {
        return {
          message: 'こんにちは!',
        }
      },
    }).mount('#app')
  }, 2000);
</script>

DEMO

CODEPEN右下の「Return」をクリックしてみてください。

See the Pen
Vue3 v-cloak
by nanimonai (@nanimonaikedo)
on CodePen.

v-cloakあり

HTML

<div id="app">
  <p v-cloak>{{ message }}</p>
</div>

CSS

[v-cloak] {
  display: none;
}

JS

<script>
  // v-cloak確認のためvueの実行を遅らせる
  window.setTimeout(() => {
    Vue.createApp({
      data() {
        return {
          message: 'こんにちは!',
        }
      },
    }).mount('#app')
  }, 2000);
</script>

DEMO

CODEPEN右下の「Return」をクリックしてみてください。

See the Pen
Vue3 v-cloak
by nanimonai (@nanimonaikedo)
on CodePen.

まとめ

Vueのディレクティブは少ないので一気に学ぶことができますね。
細かい操作は数をこなして慣れていくのが一番かと思います。
上記の他にカスタムディレクティブというオリジナルのディレクティブを作成できるものがありますが、
それはまた今度まとめようと思います。

今回参考にしたドキュメント

nanimonai

プログラム書く方が楽しいデザイナーです。デザイン事務所→フリーランス→スタートアップ入社→フリーランス(現在)。 全然更新しないのでブログは向いてないと思いつつなんとかやってます。 よければTwitterのフォローもお願いします。

カテゴリー

キーワード

デザインに必須のフリー素材サイト



関連記事