Vue基本⑥(v-属性ディレクティブ)
今回からv-属性ディレクティブについて解説していきたいと思います。
Vueではテンプレート構文として特別な属性(ディレクティブ)を用意していて、必ずv-から始まります。
1.v-text
<template>
<div>{{ count }}</div>
<div v-text="count"></div>
</template>
これは上のcountと全く同じ意味になります。
v-textは{{}}があるので基本的にあまり使いませんが、こういうv-から始まる独自の属性がいろいろあります。
2.v-html
<script setup>
import { ref } from 'vue'
const message = ref('<h1>Nyan</h1>')
</script>
<template>
<div>{{ message }}</div>
</template>
この場合
とタグはそのままテキスト表示となりますが、こうではなくmessageのみ表示させたい場合は
<script setup>
import { ref } from 'vue'
const message = ref('<h1>Nyan</h1>')
</script>
<template>
<div v-html="message"></div>
</template>
このようにv-htmlを使用し<script setup>からデータを引き出すと
<h1>タグが適用されて表示されます。
便利なのですが、セキュリティー上の問題もあります。
例えば、このmessageの内容がユーザーからもらった情報
(SNSのアプリなどで投稿機能がある)場合、悪意のあるユーザーが変なHTMLコードを書いていたら全てに適用されてしまいパスワードやクレジットカード情報など機密情報は漏洩してしまうリスクがあります。
なので、必ずv-htmlを使う時の値はユーザーからもらったデータではない信頼できるデータのみを指定しましょう。
(Webページが自由に書き換えられてしまうので)
3.v-bindディレクティブ
<script setup>
import { ref } from 'vue'
</script>
<template>
<a href="https://zenn.dev/dashboard">Zenn dashboard</a>
</template>
※v-bindディレクティブは超重要です
まず、このようにクリックするとZennのダッシュボードに飛ぶリンクを作ります。
このhrefのリンクを<script setup>内でref関数で文字列を定義します。
今までの流れだと{{}}で入れて使えそうですが
<script setup>
import { ref } from 'vue'
const zennDashboard = ref("https://zenn.dev/dashboard")
</script>
<template>
<a href="{{ zennDashboard }}">Zenn dashboard</a>
</template>
これだとうまく遷移できません。
href属性が"{{ zennDashboard }}"こういうURLが指定されたと認識をしてしまいます。
つまり、{{}}は属性の値では使えないということです。
この場合にv-bindを使用します。
<script setup>
import { ref } from 'vue'
const zennDashboard = ref('https://zenn.dev/dashboard')
</script>
<template>
<a v-bind:href="zennDashboard">Zenn dashboard</a>
</template>
hrefの前にv-bind:を持ってきて、JavaScriptのようにデータを入れれば動的に使うことができます。
これはidの属性でも使えます。例えば、
<script setup>
import { ref } from 'vue'
const zennDashboard = ref('https://zenn.dev/dashboard')
const zennId = ref('zenn-link')
</script>
<template>
<a v-bind:id="zennId" v-bind:href="zennDashboard">Zenn dashboard</a>
</template>
このようにid設定もv-bind:で動的に変えることができます。
属性であればどんなものでもv-bind:をつけることで動的に値を設定することができます。
簡単にいうと、基本的に普通の文字のところでは{{}}を使い、属性値ではv-bind:ディレクティブを使うという考え方でいいと思います。
このv-bind:は使用頻度が高いため:で省略できます。
<template>
<a :id="zennId" :href="zennDashboard">Zenn dashboard</a>
</template>
これでも同様に使用できますし、ESLintの方ではこちらが推奨されています。(コードの可読性を重要視しているのか?)
あと、v-bind:ディレクティブの属性名と属性値の変数や定数が同じ場合はイコール以下を省略できます。
const id = ref('zenn-link')
</script>
<template>
<a :id :href="zennDashboard">Zenn dashboard</a>
</template>
そして、この値にundefinedやnullを入れた場合はその属性が消えて存在しなくなり、他にも特定の属性にfalseを入れると消えるというものもあります(Boolean属性)。
HTMLの話になりますが、値を取らなくてもいい属性がBoolean属性にあたります。例えばボタンタグのdisabled属性ですが、これはBoolean属性なので値を取らなくてOKです。
これは存在するだけでボタンが使えなくなるという属性になります。
<template>
<a :id="zennId" :href="zennDashboard">Zenn dashboard</a>
<button disabled>Button</button>
</template>
このdisabled属性に対してv-bind:ディレクティブでnullやundefinedを指定した時はdisabled属性は消えるということです。
実際にundefinedを指定したらdisabledが消えてボタンが現れて使えるということです。
<template>
<a :id="zennId" :href="zennDashboard">Zenn dashboard</a>
<button :disabled="undefined">Button</button>
</template>
Boolean属性にはfalse以外にも0や-0、NaNも使用できます。
それ以外のtrueなどを入れた場合にdisabled属性が付くということになります。
空文字の時<button :disabled="''">Button</button>の時は消えません。disabled属性は残るので注意してください。
他のBoolean属性はこちら
4.v-bind:で複数の属性を指定する方法
今、このタグは2つの属性に対してv-bind:ディレクティブを適用させています。
<a :id="zennId" :href="zennDashboard">Zenn dashboard</a>
ですが、v-bind:ディレクティブには一気に複数の属性に対して適用させることもできます。
v-bind="{}"でオブジェクトのような書き方ですね。
<a v-bind="{ id:zennId, href:zennDashboard}" >Zenn dashboard</a>
見比べるとオブジェクトの書き方の方がわかりやすいかと思います。
<template>
<a :id="zennId" :href="zennDashboard">Zenn dashboard</a>
<a v-bind="{ id:zennId, href:zennDashboard}" >Zenn dashboard</a>
<button :disabled="''">Button</button>
</template>
これでv-bind:ディレクティブの説明は以上です。
次回はv-onディレクティブの説明をしていきます。
Discussion