LoginSignup
3
3

More than 3 years have passed since last update.

【Vue.js 】 カスタムディレクティブ

Posted at

はじめに

カスタムディレクティブとはv-bindのようなディレクティブを自作するための機能である。
ディレクティブではDOMがどういった操作をするのかそれぞれの属性で決まっていたが、カスタムディレクティブではDOMの操作の仕組みをカスタマイズして定義することができる。

ディレクティブとは?

テンプレートの記述できるv-から始まる属性のこと。
要素の表示/非表示、データバインディングなどといったDOM操作ができる。

カスタムディレクティブの登録方法

グローバル、ローカルのどちらでも定義できる。

ローカルへの登録

directivesオプションに登録することで特定のコンポーネントでカスタムディレクティブが使用できる。

sample.vue
// example という名前のカスタムディレクティブを登録
new Vue({
  el: 'app',
  directives: {
    example: {
    }
  }
})

グローバルへの登録

グローバルメソッドVue.directiveメソッドを使用してグローバルに登録することで全てのコンポーネントでカスタムディレクティブが使用できる。

sample.vue
<script>
// example という名前のカスタムディレクティブを登録
Vue.directive('example',{
});
</script>

登録したカスタムディレクティブを使用

カスタムディレクティブとして登録したメソッド名にv-(プレフィックス)をつけて使用する。

sample.vue
<template>
  <div v-example>カスタムディレクティブ</div>
  <!-- ↓ カスタムディレクティブのトリガとなるデータをバインドすることもできる -->
  <!-- valueが変化すれば必ず呼び出される -->
  <div v-example="value">カスタムディレクティブ</div>
</template>

使用可能なフック

カスタムディレクティブはオプションで下記のフックが使用できる。
ここでいうフックとは処理をひっかけるようなこと。下記のタイミングで処理を実行する。

メソッド名 タイミング
bind ディレクティブがはじめて要素と結びついた時
inserted 紐づいた要素が親Nodeに挿入された時
update 紐づいた要素を包含しているコンポーネントのVNodeが更新された時
componentUpdated 紐づいた要素を包含しているコンポーネントと子コンポーネントのVNodeが更新された時
unbind 紐づいていた要素からディレクティブが削除される時

※ VNodeとは仮想DOMのNodeのこと。updatecomponentUpdatedは仮想DOMが更新されたときに呼び出される。

それぞれの動作を確認してみる

sample.vue
<div id="app">
  <input type="text" v-example>
</div>
sample.vue
<script>
Vue.directive('example',{
  bind: function(el, binding) {
    console.log('bind')
  },
  inserted: function(el, binding) {
    console.log('inserted')
  },
  update: function(el, binding) {
    console.log('update')
  },
  componentUpdated: function(el, binding) {
    console.log('componentUpdated')
  },
  unbind: function(el, binding) {
    console.log('unbind')
  },
})
</script>

この状態でinputを操作するとbindinsertedのフックしか作動しない。
仮想DOMが更新されていないのでupdatecomponentUpdatedは呼び出されない。

sample.vue
<div id="app">
  <input type="text" v-model="value" v-example>
</div>

↑ のようにinputの値を動的にすることで仮想DOMが更新され、updatecomponentUpdatedも呼び出すことができるようになり、データを監視しながらDOMを操作することができる。

フックの引数

引数 内容
el ディレクティブが付与されている要素
binding バインドされた値、引数、修飾子のオブジェクト
vnode 要素に対応するVNode
oldVnode 更新前のVnode(updat、componentUpdatedでのみ使用可)
前の状態と比較して処理を行う

引数bindingにはバインドされたものに関するいくつかの情報が入っている。

bindingのもつプロパティの1つにoldValuevalueがある。
oldValueは古いバインドデータを持っているのでoldValuevalueで新しいデータと古いデータを比較することができる。

↓ あるinputの値が変化したときの変更前と変更後の値が格納されるようにする

sample.vue
<input type="text" v-model="value" v-example="value"/>

カスタムディレクティブにデータvalueを渡す。
これによりbindingのoldValueとvalueには変更前の値と変更後の値が格納される。

sample.vue
<script>
Vue.directive('example',{
  update: function(el, binding) {
    console.log('update');
    // 古いデータ
    console.log('前回' + binding.oldValue);
    // 新しいデータ
    console.log('今回' + binding.value);
  }
})
</script>
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3