まずディレクティブとは
v-textとかv-modelとかv-ifとか
これ、自分で作れる!
それがカスタムディレクティブという
どんな時に使うかというと🤔
- コードを抽象化したい
- コードを再利用したい
時に使います
再利用したいときは基本的にはコンポーネントを使いますが、もっと複雑なものを作りたい時にカスタムディレクティブを使います。
App.vue
<template>
<p v-border>Home</p>
<!-- bindのタイミング・・・v要素が初めてpタグに結びついた時 -->
</template>
main.js
//コンポーネントと同じように、引数は2つとる。
//1つ目は名前。border(v-●●の●●の部分)
Vue.directive("border",{
//2つ目の引数はオブジェクト
//5個のメソッドをとる
//フック関数ともいう
bind(el,binding,vnode){},
//⬆️ディレクティブが初めて対象の要素に紐づいた時(最初の一回のみ)
inserted(el,binding,vnode,oldVnode){},
//⬆️実際の親DOMnodeに挿入された時
//mounted的な
updated(el,binding,vnode){},
//コンポーネント(Home.vue)が更新された時 (コンポーネントのVNodeの状態で)
componentUpdated(el,binding,vnode,oldVnode){},
unbind(el,binding,vnode){}
});
主にこんな感じで書きますが、
二つ目の引数でよく使うものは、
bind
とupdated
で基本的に同じような内容を書きます。
同じような内容を書くので、省略記法があります。
カスタムディレクティブの二つ目の引数は
オブジェクトとmain.jsの方に書きましたが、オブジェクトである必要はなく、そのまま関数を書いていっちゃいます。
main.js
//functionの引数は、oldVnodeとかもかける
//{}内に書いたものは、bindとupdatedに適用される
Vue.directive("border",function(el,binding){
//elとは紐づく要素を示す(どのHTML要素とつながるか)
//今回はv-borderはpタグのとこに入ってるのでpタグと繋がる
el.style.border ="solid black 2px";
//el.style.borderWidth = '5px'
//⬆️これを動的に渡すとすると、以下のように書く
el.style.borderWidth = binding.value;
});
このborder
とwidth
を一緒に書く場合は、オブジェクトで書きます!
App.vue
<template>
<!--
二つ以上のデータを渡すときは渡すデータをオブジェクトにしちゃう -->
<p v-border="{width:'5px',color:'red'}">Home</p>
</template>
ほんで
main.js
Vue.directive("border",function(el,binding){
el.style.borderWidth = binding.value.width;
el.style.borderColor = binding.value.color;
});
こんな感じで
引数をとる場合
カスタムディレクティブの後に引数を取り、
jsの方でargと書きます
※引数は一つしか取れない
App.vue
<template>
<!-- :の後に入るのは引数 -->
<p v-border:dotted="{width:'5px',color:'red'}">Home</p>
</template>
main.js
Vue.directive("border",function(el,binding){
//arg = argument = 引数
el.style.borderStyle = binding.arg;
});