【Javascript】Vue3のディレクティブまとめ
Index
ディレクティブとは?
ディレクティブは、HTML要素(DOM要素)に追加の動作を追加するVue.jsの独自の属性です。
Vueの組み込みディレクティブを使用して、フォーム、リスト、スタイルやユーザーに表示される内容を操作・管理することができます。
Vue3のディレクティブの分類
分類 | ディレクティブ | 説明 |
---|---|---|
データバインド(表示)系 | v-text,v-bind,v-html,v-onceなど | データをページに反映・表示 |
イベント系 | v-on | イベント処理を実行 |
フォーム(データのやり取り)系 | v-model | フォームからの入力を取得 |
制御系 | v-if,v-forなど | 条件分岐や繰り返し処理を実行 |
データバインドとは?
bind(バインド)・・・(…を)結び合わせる、結びつける。の意味。
データ バインディングとは、アプリ側の UI と、そこに表示されるデータを同期(接続)する処理です。 バインドが適切に設定され、データから適切な通知が提供される場合、データの値が変更されると、そのデータにバインドされている要素に変更が自動的に反映されます。
Vue3のディレクティブまとめ
v-text
v-textは、要素内にコンテンツをバインド(表示)します。
既にコンテンツが挿入されている場合は上書きとなります。
HTML
<div id="app">
<!-- 以下2つは同じ意味。表現が異なるだけ -->
<p v-text="message">既存のコメント</p>
<p>{{ message }}</p>
</div>
JS
<script>
Vue.createApp({
data(){
return {
message: 'Hello Vue js!'
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Untitled by nanimonai (@nanimonaikedo)
on CodePen.
v-bind
htmlタグの属性に対してv-textの{{…}}だけでは利用できません。
属性値の操作にはv-bindを使用します。
:のみと省略することもできますが、はじめのうちはv-bindを記述しておくことがおすすめです。
HTML
<div id="app">
<p><a v-bind:href="url" target="_blank">google</a></p>
<!-- 省略形 -->
<p><a :href="url" target="_blank">google</a></p>
<!-- これでは動かない -->
<p><a href="{{url}}" target="_blank">google</a></p>
</div>
JS
<script>
Vue.createApp({
data(){
return {
url: 'https://www.google.com'
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Untitled by nanimonai (@nanimonaikedo)
on CodePen.
v-html
v-htmlは、{{ … }}の中身をテキストではなくhtmlとして出力します。
HTML
<div id="app">
<p>v-text: <span v-text="htmlText"></span></p>
<p>v-html: <span v-html="htmlText"></span></p>
</div>
JS
<script>
Vue.createApp({
data(){
return {
htmlText: '<span style="color: red;">RED</span>'
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Untitled by nanimonai (@nanimonaikedo)
on CodePen.
v-pre
v-preは、要素内のvueコードをテキストとしてそのまま表示します。
HTML
<div id="app">
<p v-pre>{{ message }}</p>
<p>{{ message }}</p>
</div>
JS
<script>
Vue.createApp({
data(){
return {
message: 'Hello Vue js!'
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Vue3 v-pre by nanimonai (@nanimonaikedo)
on CodePen.
v-once
v-onceは、一度目だけ変数が変更した場合に更新を行います。
2回目以降は変数が変更しても更新されません。
HTML
<div id="app">
<form v-on:submit.prevent>
<label for="textBox">テキスト: </label>
<input type="text" id="textBox" v-model="text">
</form>
<div v-once>再描画なし: {{text}}</div>
<div>再描画あり: {{text}}</div>
</div>
JS
<script>
Vue.createApp({
data(){
return {
text: '初期値'
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Untitled by nanimonai (@nanimonaikedo)
on CodePen.
v-on
v-onは主に、マウス動作時などイベント発生時のJavaScriptの実行を関連付けられます。@と省略することもできますが、はじめのうちはv-onを記述しておくことがおすすめです。
HTML
<div id="app">
<button v-on:click="countUp(2)">Add</button>
<!-- 省略形 -->
<button @click="countDown(2)">Remove</button>
<p>Clicked {{ count }} times.</p>
</div>
JS
<script>
Vue.createApp({
data() {
return {
count:0 //初期値
}
},
methods:{
countUp(num){
this.count += num
},
countDown(num){
this.count -= num
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Count num by nanimonai (@nanimonaikedo)
on CodePen.
利用できる主なイベント
分類 | イベント名 | 説明 |
---|---|---|
フォーム | focus | 要素にフォーカスが入ったとき |
blur | 要素からフォーカスが外れたとき | |
change | 要素の値を変更したとき(input,select,textareaなど) | |
select | テキストボックス/テキストエリアのテキストを選択したとき | |
submit | フォームから送信したとき | |
マウス操作 | click | 要素をクリックしたとき |
dbclick | 要素をダブルクリックしたとき | |
mousedown | マウスのボタンを押したとき※クリックとは異なる | |
mouseenter | 要素エリアにマウスポインターが入ったとき | |
mouseleave | 要素エリアからマウスポインターが外れたとき | |
mouseover | 要素エリアにマウスオーバーしたとき | |
mouseout | 要素エリアからマウスアウトしたとき | |
mousemove | 要素の中をマウスポインターが移動したとき | |
mouseup | マウスのボタンを離したとき ※mousedownとmouseupの一連の動きがclickと同等 | |
キー操作 | keydouwn | キーを押したとき |
keyup | キーを離したとき | |
keypress | キーを押し続けているとき | |
その他 | resize | ウィンドウサイズが変更したとき |
scroll | スクロールしたとき | |
error | ページ内エラーが発生したとき | |
contextmenu | コンテキストメニューを表示するまえ |
v-model
v-modelは、formのinput要素やtextarea要素、select要素と双方向のデータバインディングを行います。
自動的に入力要素の更新が可能です。
value, checkedやselected属性の初期値は無視されるので注意が必要です。
入力ボックスのサンプル
HTML
<div id="app">
<input type="text" v-model="message">
<p>入力内容 : {{ message }}</p>
</div>
JS
<script>
Vue.createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Vue3 v-model by nanimonai (@nanimonaikedo)
on CodePen.
チェックボックスのサンプル
HTML
<div id="app">
<form action="">
<div>OSを選んでください。</div>
<input type="checkbox" id="windows" value="Windows" v-model="os">
<label for="windows">Windows</label>
<input type="checkbox" id="linux" value="Linux" v-model="os">
<label for="linux">Linux</label>
<input type="checkbox" id="mac" value="MacOS" v-model="os">
<label for="mac">MacOS</label>
</form>
<p>選択:{{ os }}</p>
</div>
JS
<script>
Vue.createApp({
data() {
return {
os: []
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Vue3 v-model checkbox by nanimonai (@nanimonaikedo)
on CodePen.
v-slot
v-slotは呼び出し元のコンテンツを呼び出し先テンプレートに埋め込むことが出来ます。
HTML
<div id="app">
<hello-tpl>山田</hello-tpl>
</div>
JS
<script>
Vue.createApp({})
.component('hello-tpl', {
template:`<div>こんにちは<slot>ゲスト</slot>さん!</div>`,
})
.mount('#app')
</script>
スロットはテンプレート内に<slot>要素を埋め込みます。
これによって呼び出し側のコンテンツが、<slot>要素の合った場所に表示されます。
DEMO
See the Pen
Vue3 v-slot by nanimonai (@nanimonaikedo)
on CodePen.
イメージ
v-if, v-else, v-else-if
v-ifディレクティブは、ブロックを条件に応じて表示したい時に使用されます。
v-else-ifとv-else要素は、それぞれv-if要素あるいはv-else-if要素の直後に書く必要があります。
HTML
<div id="app">
<p v-if="flag">
これはTrueの状態です。
</p>
<p v-else>
これはFalseの状態です。
</p>
<button v-on:click="chaneFlag()">ボタンを押してね。</button>
</div>
JS
<script>
Vue.createApp({
data() {
return {
flag: true
}
},
methods:{
chaneFlag:function(){
this.flag = !this.flag
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Vue3 v-if,v-else-if,v-else by nanimonai (@nanimonaikedo)
on CodePen.
v-show
v-showは、式の値の真偽に基づいて、要素の表示・非表示をトグルします。
v-ifでは要素自体をDOMに表示しないのに対し、v-showではdisplay:none;で非表示にします。
処理速度はv-showの方が早く、繰り返し処理のv-forとv-ifの組み合わせは推奨されないので、複数のトグル要素を使用するときは、v-showを使用します。
HTML
<div id="app">
<p v-show="flag">
こんにちは!
</p>
<button v-on:click="chaneFlag()">ボタンを押してね。</button>
</div>
JS
<script>
Vue.createApp({
data() {
return {
flag: true
}
},
methods:{
chaneFlag:function(){
this.flag = !this.flag
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Untitled by nanimonai (@nanimonaikedo)
on CodePen.
v-for
v-forは配列やオブジェクトから順番に要素を取り出します。JavaScriptのforに当たります。
HTML
<div id="app">
<ul>
<li v-for="(item, index) in items" :key="item.title">
{{index}} : {{item.title}} : {{item.author}} : {{item.published}}
</li>
</ul>
<hr>
<ul>
<li v-for="(value, key, index) in books">
{{index}} : {{key}} : {{value}}
</li>
</ul>
</div>
JS
<script>
Vue.createApp({
data() {
return {
items:[
{title:'Romeo and Juliet ', author:'William Shakespeare', published:'1595'},
{title:'Hamlet', author:'William Shakespeare', published:'1601'},
{title:'Macbeth', author:'William Shakespeare', published:'1606'},
],
books:{
title:'Hamlet',
author:'William Shakespeare',
published:'1601',
}
}
},
}).mount('#app')
</script>
DEMO
See the Pen
Vue3 v-for by nanimonai (@nanimonaikedo)
on CodePen.
v-memo
v-memoは、指定した値が最後のレンダリング結果と同じであれば、再レンダリング(更新)をスキップします。膨大なリストの中で変更があったDOMのみ更新させることで、パフォーマンスを最適化するのが目的です。
最適化の効果は1000件を超えるリストなどの描画の時に有効とあるので、大規模なデータを扱わない限りは使わなそうです。
HTML
<div id="app">
<select v-model="selectedItem" v-on:change="selectItem">
<option
v-for="item in items"
v-bind:key="item.id"
v-bind:value="item.id"
>
{{ item.name }}
</option>
</select>
<div v-for="item in items" :key="item.id" v-memo="[item.id, selectedItem]">
<p v-if="item.id === selectedItem">{{item.name}} : selected ← ここだけ更新</p>
<p v-else-if="item.id === preselectedItem">{{item.name}} : unselect ← ここだけ更新</p>
<p v-else="item.id === selectedItem">{{item.name}} : unselect ← 更新しない</p>
</div>
</div>
JS
<script>
Vue.createApp({
data() {
return {
items:[
{ id: 1, name:'ITEM1' },
{ id: 2, name:'ITEM2' },
{ id: 3, name:'ITEM3' },
{ id: 4, name:'ITEM4' },
{ id: 5, name:'ITEM5' },
{ id: 6, name:'ITEM6' },
{ id: 7, name:'ITEM7' },
{ id: 8, name:'ITEM8' },
{ id: 9, name:'ITEM9' },
],
selectedItem:1,
preselectedItem:1,
}
},
methods:{
selectItem:function(e){
this.preselectedItem = this.selectedItem
}
}
}).mount('#app')
</script>
DEMO
See the Pen
Untitled by nanimonai (@nanimonaikedo)
on CodePen.
v-cloak
v-cloakはアクセス時のマスタッシュ(ダブルカーリーブレイス)を表示させないように設定することができます。
ブラウザでindex.htmlファイルを開くと一瞬画面上に{{ … }}が表示されてしまいます。
表示されるのは非常に短い時間のでどのようなものが表示されるかまでわからない場合もあります。
v-cloakなし
HTML
<div id="app">
<p>{{ message }}</p>
</div>
CSS
[v-cloak] {
display: none;
}
JS
<script>
// v-cloak確認のためvueの実行を遅らせる
window.setTimeout(() => {
Vue.createApp({
data() {
return {
message: 'こんにちは!',
}
},
}).mount('#app')
}, 2000);
</script>
DEMO
CODEPEN右下の「Return」をクリックしてみてください。
See the Pen
Vue3 v-cloak by nanimonai (@nanimonaikedo)
on CodePen.
v-cloakあり
HTML
<div id="app">
<p v-cloak>{{ message }}</p>
</div>
CSS
[v-cloak] {
display: none;
}
JS
<script>
// v-cloak確認のためvueの実行を遅らせる
window.setTimeout(() => {
Vue.createApp({
data() {
return {
message: 'こんにちは!',
}
},
}).mount('#app')
}, 2000);
</script>
DEMO
CODEPEN右下の「Return」をクリックしてみてください。
See the Pen
Vue3 v-cloak by nanimonai (@nanimonaikedo)
on CodePen.
まとめ
Vueのディレクティブは少ないので一気に学ぶことができますね。
細かい操作は数をこなして慣れていくのが一番かと思います。
上記の他にカスタムディレクティブというオリジナルのディレクティブを作成できるものがありますが、
それはまた今度まとめようと思います。