寝て起きて寝て

プログラミングが出来ない情報系のブログ

カスタムディレクティブ

カスタムディレクティブとは

v-ifv-showなどのディレクティブを自分で作成し使用できる機能。

抽象化したコードを再利用した場合などに使用する

使い方

コンポーネントで共通にしたい場合App.vue
1コンポーネント内でのみ使用したい場合は各コンポーネントで記載する

作成したディレクティブを使用する場合はディレクティブ名の頭にv-を付ける
なので作成時はv-は必要ない

グローバルの場合

new Vueの前で設定する

Vue.directive("ディレクティブ名",{ディレクティブの設定})

ローカルの場合

export default{
  directives:{
    ディレクティブ名(){
      ディレクティブの設定(){}
    }
  }
}

記載方法

Vue.directive("test",{
  bind(el, binding, vnode){
    //ディレクティブが初めて対象の要素に紐付いた時
  },
  inserted(el, binding, vnode){
    //親Nodeに挿入された時
  },
  update(el, binding, vnode, oldVnode){
    //コンポーネントが更新されるたび呼び出される。子コンポーネントが更新される前
  },
  componentUpdated(el, binding, vnode, oldVnode){
    //コンポーネントが更新されるたび呼び出される。子コンポーネントが更新された後
  },
  unbind(el, binding, vnode){
    //ディレクティブが紐付いている要素から取り除かれた時
  }
})

bind

template内の属性に初めて紐付いた時に1度だけ呼び出される関数

inserted

DOM内に挿入された時発火。コンポーネントでいうmountedのようなもの

update

コンポーネント内で仮想DOMに変化が起こった場合に発火
コンポーネントのVNodeが更新される前に発火されるため注意

componentUpdated

update関数の子コンポーネントのVNodeが更新されたバージョン

unbind

コンポーネントでいうdestroyedのようなもの
ディレクティブが紐ついて要素から取り除かれたときに発火

省略記法

実際よく使用するのはbindupdateなのでこの2つ似関しては、
省略して記載することができる

Vue.directive("test",function(el, binding, vnode, oldVnode){
  //bindとupdateをまとめて書くとこうなる
})

また、vnode系の引数はあまり使用しないため記載しないで、
その2つを除いたもので書くことが多い

Vue.directive("test",function(el, binding){

})

実際に設定する

<template>
  <p v-test>Test</p>
</template>

<script>
  Vue.directive("test",function(el, binding){

  })
</script>

まず引数のelはhtml側のp要素のことを指しているなので、

  Vue.directive("test",function(el, binding){
    el.style.border = "solid black 2px"
  })

上のように指定するとカスタムディレクティブを指定した要素に枠組みを
付けることができる

bindingに関しては、様々な機能があるが
主にhtml側からデータが渡された場合は

<template>
  <p v-test="32px">Test</p>
</template>

<script>
  Vue.directive("test",function(el, binding){
    el.style.fontSize= "binding.value"
  })
</script>

また2つ以上のデータを渡したい場合はオブジェクトにして
html側から値を渡すことで設定可能になる

またhtmlから引数を渡したい場合はbinding.argで取得することができる 今回の引数はdotted

引数には一つしか取ることができない

<template>
  <p v-test:dotted={size:"32px",color:"red"}>Test</p>
</template>

<script>
  Vue.directive("test",function(el, binding){
    el.style.fontSize= binding.value.size
    el.style.borderColor= binding.value.color
    el.style.borderStyle= binding.arg
  })
</script>

修飾子も指定できる

今回はroundという修飾子を付ける この修飾子はいくつもつなげて書ける

<template>
  <p v-test:dotted.round={size:"32px",color:"red"}>Test</p>
</template>

<script>
  Vue.directive("test",function(el, binding){
    el.style.fontSize= binding.value.size
    el.style.borderColor= binding.value.color
    el.style.borderStyle= binding.arg
    if(binding.modifiers.round){// 付いていればtrue なければfalse
      el.style.borderRadius = "0.5rem"
    }
  })
</script>