カスタムディレクティブ
カスタムディレクティブとは
v-if
やv-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のようなもの
ディレクティブが紐ついて要素から取り除かれたときに発火
省略記法
実際よく使用するのはbind
とupdate
なのでこの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>