mcaz
8/28/2019 - 11:41 PM

Vue.directive


function consoleDirectiveFookArguments(type, el, binding) {
  console.log('------------------------------------------');
  console.log('custom directive=button-click : ' + type);
  console.log('el: %o', el);
  console.log('binding: %o', binding);
  console.log('------------------------------------------');
}

Vue.directive('fallback-image', {
  bind: function(el, binding) {
    consoleDirectiveFookArguments('fallback-image.bind', el, binding);

    el.addEventListener('error', function() {
      el.src = 'https://dummyimage.com/500x100/000/ffffff.png&text=no+image'
    });
  },
  update: function(el, binding) {
    consoleDirectiveFookArguments('fallback-image.update', el, binding);

    if (binding.value === binding.oldValue) return;
  }
});

Vue.directive('custom-directive', {

  /**
   * ディレクティブが対象の要素に紐付いた一度だけ呼ばれる。
   * 初回のセットアップ処理を実行
   * 要素のイベントリスター登録等に使用
   * @param {Element} el ディレクティブが紐づく要素
   * @param {Object}  binding
   */
  bind: function(el, binding) {
    consoleDirectiveFookArguments('bind', el, binding);
  },
  /**
   * 紐付いた要素が親要素に挿入されたときに呼ばれる
   * 親要素が存在することを保証されるが、ドキュメントに要素がアタッチされていることは保証しない
   * @param {Element} el
   * @param {Object}  binding
   */
  inserted: function(el, binding) {
    consoleDirectiveFookArguments('inserted', el, binding);
  },
  /**
   * ディレクティブの値が変化などに伴って、紐付いた要素を含んでいるコンポーネントのVNodeが更新されるたびに呼ばれる
   * ディレクティブの値が変化しない場合でも呼ばれる場合がある。
   * その場合は以前の値と比較する等の処理が必要になる
   * @param {Element}  el ディレクティブが紐づく要素
   * @param {Object}   binding
   * @param {Object}   binding.def ディレクティブ定義オブジェクト
   * @param {Function} binding.def.bind
   * @param {Function} binding.def.inserted
   * @param {Function} binding.def.updated
   * @param {Function} binding.def.componentUpdated
   * @param {Function} binding.def.unbind
   * @param {String}   binding.name prefix(v-)なしのディレクティブ名
   * @param {String}   binding.rawName ディレクティブ名
   * @param {String}   binding.expression 文字列としてのバインディング式、ディレクティブ設定時に渡す
   *  <button v-custom-directive="expressionValue">aaa</button> => 'expressionValue'
   * @param {String}   binding.arg ディレクティブに渡される引数、ディレクティブ設定時に渡す
   *  <button v-custom-directive:foo>aaa</button> => 'foo'
   * @param {Object}   binding.modifiers 装飾子を含んだオブジェクトを参照できる、ディレクティブ設定時に渡す
   *  <button v-custom-directive.foo.bar>aaa</button> => {foo: true, bar: true}
   * @param {String}   binding.oldArg
   * @param {String}   binding.value   
   * @param {String}   binding.oldValue
   */
  updated: function(el, binding) {
    consoleDirectiveFookArguments('updated', el, binding);

    if (binding.value === binding.oldValue) return;

    // ディレクティブの値に変更がある
    // DOM操作を行う際に確認をすることで不要な処理を避ける
  },
  /**
   * コンポーネントのVNodeと子コンポーネントのVNodeが更新された場合に呼ばれる。
   * @param {Element} el
   * @param {Object}  binding
   */
  componentUpdated: function(el, binding) {
    consoleDirectiveFookArguments('componentUpdated', el, binding);
  },
  /**
   * ディレクティブが紐付いている要素から取り除かれた際、1度だけ呼ばれる。
   * bindで登録したインベントリスナーの削除等の後始末処理を行う。
   * @param {Element} el
   * @param {Object}  binding
   */
  unbind: function(el, binding) {
    consoleDirectiveFookArguments('unbind', el, binding);
  },
});
<button
  v-custom-directive:foo="expressionValue"
  @click="updateButton">update!</button>
</button>