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

デフォルトで設定されているコアディレクティブ(v-modelおよびv-show)以外、Vueではカスタムディレクティブの登録も可能です。

次にはグローバルディレクティブv-focusを登録します。このディレクティブの機能は、ページがロードされる場合、要素にフォーカスを当てます。

<div id="app">
	<p>ページがロードされる場合、input 要素にフォーカスを当てる:</p>
	<input v-focus>
</div>

<script>
// グローバルディレクティブv-focusを登録する
Vue.directive('focus', {
  //バンティングされている要素が DOM に挿入される時
  inserted: function (el) {
    // 要素にフォーカスを当てる
    el.focus()
  }
})
// ルートインスタンスを作成する
new Vue({
  el: '#app'
})
</script>

インスタンスでdirectivesオプションを使用してローカルディレクティブを登録できるため、ディレクティブはこのインスタンスでのみ使用できます。

<div id="app">
  <p>ページがロードされる場合、input 要素にフォーカスを当てる:</p>
  <input v-focus>
</div>

<script>
// ルートインスタンスを作成する
new Vue({
  el: '#app',
  directives: {
    // ローカルディレクティブv-focusを登録する
    focus: {
      // ディレクティブの定義
      inserted: function (el) {
        // 要素にフォーカスを当てる
        el.focus()
      }
    }
  }
})
</script>

フック

フック関数

ディレクティブ定義関数はいくつかのフック関数(オプション)を提供します。

  • bind:1回だけ呼び出されます。ディレクティブが要素に初めてバインドされたときに呼び出されます。このフック関数を使用して、バインドする時1回にセットアップ処理を実行します。
  • inserted:バインドされた要素が親 Nodeに挿入されたときに呼び出されます。(親 Nodeは呼び出すことができ、ドキュメントに存在する必要はありません)
  • update:バインドされた値が変更されたかどうかに関係なく、バインドされた要素が配置されているテンプレートが更新されたときに呼び出されます。更新前後のバインディング値を比較することにより、必要がないテンプレートの更新を無視できます。(フック関数の引数の詳細については、下記を参照してください)
  • componentUpdated:バインドされた要素のテンプレートが更新サイクルを完了したときに呼び出されます。
  • unbind:ディレクティブが要素からバインド解除されたときに、1回だけ呼び出されます。

フック関数の引数

フック関数の引数は次のとおりです。

  • el: ディレクティブによってバインドされた要素を使用して、DOMを直接操作できます。
  • binding: 以下のプロパティを含んでいるオブジェクトです。
  • name: v- 接頭辞 (prefix) 無しのディレクティブ名。
  • value: ディレクティブにバインドされる値です。例えば :v-my-directive=”1 + 1″の値は2です。
  • oldValue: ディレクティブによってバインドされた以前の値は、updateとcomponentUpdatedでのみ使用できます。 値が変化するかどうかに関係なく使用できます。
  • expression: バインドされた値の式または変数名です。例えば、v-my-directive = “1 + 1″の値は “1 +1″です。
  • arg: ディレクティブに渡される引数です。例えば v-my-directive:foo では、arg の値は “foo” です。
  • modifiers: 修飾子を含むオブジェクトです。 例:v-my-directive.foo.bar、修飾子オブジェクトのmodifiersの値は{foo:true、bar:true}です。
  • vnode: Vueコンパイルによって生成された仮想ノードです。
  • oldVnode: update と componentUpdated フックにおいてのみ利用できる以前の仮想ノードです。

次には、これらの引数の例を示しています。

<div id="app"  v-runoob:hello.a.b="message">
</div>

<script>
Vue.directive('runoob', {
  bind: function (el, binding, vnode) {
    var s = JSON.stringify
    el.innerHTML =
      'name: '       + s(binding.name) + '<br>' +
      'value: '      + s(binding.value) + '<br>' +
      'expression: ' + s(binding.expression) + '<br>' +
      'argument: '   + s(binding.arg) + '<br>' +
      'modifiers: '  + s(binding.modifiers) + '<br>' +
      'vnode keys: ' + Object.keys(vnode).join(', ')
  }
})
new Vue({
  el: '#app',
  data: {
    message: 'Florian Studio'
  }
})
</script>

他のフック関数が必要ない場合も、次のように関数を省略できます。

Vue.directive('runoob', function (el, binding) {
  // ディレクティブの背景色を設定する
  el.style.backgroundColor = binding.value.color
})

ディレクティブ関数は、すべての有効なJavaScript式を受け入れることができます。次の例では、JavaScriptオブジェクトが渡されます。

<div id="app">
    <div v-runoob="{ color: 'green', text: 'Florian Studio' }"></div>
</div>

<script>
Vue.directive('runoob', function (el, binding) {
	// テキストと背景色を設定する簡単な記法
	el.innerHTML = binding.value.text
	el.style.backgroundColor = binding.value.color
})
new Vue({
  el: '#app'
})
</script>

Share

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です