Vue.jsのcomputed
kurumin
プログラミングのーと
マスタッシュ構文はタグとタグに囲まれた部分(要素のテキスト)にしか使えない。
属性にテンプレート変数を利用したい場合は、データバインディングのディレクティブを利用する。
テンプレートブロックでHTMLタグ内に記述するv-で始まる属性のこと。
| ディレクティブ | 役割 |
|---|---|
| v-vind | データバインディング |
| v-on | イベント処理 |
| v-model | 双方向データバインディング |
| v-html | HTML文字列表示 |
| v-pre | 静的コンテンツ表示 |
| v-once | データバインディングを初回のみに制限 |
| v-clock | マスタッシュ構文の非表示 |
| v-if | 条件分岐 |
| v-show | 表示/非表示の制御 |
| v-for | ループ処理 |
本記事ではv-onの学習をする。(v-vindは次回)
<script setup lang="ts">
import { ref } from "vue";
const url = ref("https://vue.js.org/")
</script>
<template>
<!-- 基本的な記述 -->
<p><a v-bind:href="url" target="_blank">Vue.jsのサイト</a></p>
<!-- 省略した記述。可読性という視点では非推奨。 -->
<p><a :href="url" target="_blank">Vue.jsのサイト(省略形)</a></p>
<!-- 式が記述できる -->
<p><a v-bind:href="url + 'guide/introduction.html'" target="_blank">Vue.jsガイドのぺージ</a></p>
</template>要素の△△の属性として、テンプレート変数〇〇の値を設定する
属性(△△)の部分をディレクティブの引数という。
disabledやreadonlyなど、属性値のない属性にもv-bindを使うことができる。
値としてtrueかfalseを使用する。
<script setup lang="ts">
import { ref } from "vue";
const isSendButtonDisabled = ref(true);
</script>
<template>
<p><button type="button" v-bind:disabled="isSendButtonDisabled">送信</button></p>
</template>ブラケット[]を使用すると属性をテンプレート変数として指定できる。
v-bindの引数もテンプレート変数で指定する方法を動的引数という。
<script setup lang="ts">
import { ref } from "vue";
const widthOrHeight = ref("height");
const widthOrHeightValue = ref(100);
</script>
<template>
<p><img src="./assets/logo.svg" alt="" v-bind:[widthOrHeight]="widthOrHeightValue"></p>
</template>引数を指定せずにv-bindを使うと、複数の属性をまとめてバインドできる。
<script setup lang="ts">
import { ref } from "vue";
const imgAttributes = ref({
src: "/images/logo.svg",
alt: "Vueのロゴ",
width: 75,
height: 75
});
</script>
<template>
<p><img v-bind="imgAttributes"></p>
</template>
<!-- レンダリング結果 -->
<p><img src="/images/logo.svg" alt="Vueのロゴ" width="75" height="75"></p>なお、imgタグに直接属性を記述した場合、v-bindよりも直接記述した値の方が優先される。
<script setup lang="ts">
import { ref, computed } from "vue";
const msg = ref("スタイル属性へバインディング");
const msgTextRed = ref("red");
const msgTextColor = ref("white");
const msgBgColor = ref("black");
const msgStyles = ref({
color: "white",
backgroundColor: "black"
});
const msgStyles2 = ref({
fontSize: "24px"
});
const msgStyles3 = ref({
color: "pink",
fontSize: "24px"
});
// 文字サイズをランダムで変更
const textSize = computed(
(): string => {
const size = Math.round(Math.random() * 25) + 10;
return `${size}pt`;
}
);
</script>
<template>
<p v-bind:style="{ color: msgTextRed }">①{{ msg }}</p>
<p v-bind:style="{ color: 'pink' }">②{{ msg }}</p>
<!-- 文字サイズをランダムで変更 -->
<p v-bind:style="{ fontSize: textSize }">③{{ msg }}</p>
<!-- 複数のCSSを指定。スタイルプロパティはキャメル記法で記述する必要があるが、''を付ければケバブ記法でも動作する -->
<p v-bind:style="{ color: msgTextRed, backgroundColor: msgBgColor }">④{{ msg }}</p>
<p v-bind:style="{ color: msgTextRed, 'background-color': msgBgColor }">⑤{{ msg }}</p>
<!-- オブジェクト側でCSSを複数指定 -->
<p v-bind:style="msgStyles">⑥{{ msg }}</p>
<!-- オブジェクトを配列として指定 -->
<p v-bind:style="[msgStyles, msgStyles2]">⑦{{ msg }}</p>
<!-- 複数のオブジェクトで同一のプロパティが指定されていた場合は、後に記述したオブジェクトで上書きされる -->
<p v-bind:style="[msgStyles, msgStyles3]">⑧{{ msg }}</p>
<p v-bind:style="[msgStyles3, msgStyles]">⑨{{ msg }}</p>
</template>レンダリング結果は以下。
<p style="color: red;">①スタイル属性へバインディング</p>
<p style="color: pink;">②スタイル属性へバインディング</p>
<p style="font-size: 35pt;">③スタイル属性へバインディング</p>
<p style="color: red; background-color: black;">④スタイル属性へバインディング</p>
<p style="color: red; background-color: black;">⑤スタイル属性へバインディング</p>
<p style="color: white; background-color: black;">⑥スタイル属性へバインディング</p>
<p style="color: white; background-color: black; font-size: 24px;">⑦スタイル属性へバインディング</p>
<p style="color: pink; background-color: black; font-size: 24px;">⑧スタイル属性へバインディング</p>
<p style="color: white; font-size: 24px; background-color: black;">⑨スタイル属性へバインディング</p>v-bind:style="{スタイルプロパティ: 値, ・・・}"スタイルプロパティはキャメル記法(fontSize、backgroundColorなど)で記述する。
style属性へのバインディングも可能だが、メンテナンス性を考えるとクラス名を利用したclass属性へのバインディングの方が望ましい。
この場合は、v-bind:classを利用する。
<script setup lang="ts">
import { ref, computed } from "vue";
const msg = ref("クラス属性へバインディング");
// スタイル適用の有無はtrueかfalseで指定する。
const isTextColorRed = ref(true);
const isBgColorBlue = ref(false);
const styles = ref({
textColorRed: false,
bgColorBlue: true
});
const computedStyles = computed(
(): { textColorRed: boolean; bgColorBlue: boolean; } => {
// 乱数を利用して0か1を生成(TextColorRed用)
const randText = Math.round(Math.random());
// textColorRedプロパティの値を表す変数をtrueで用意。
let textColorFlg = true;
// 発生した乱数が0ならばfalseに変数。
if (randText == 0) {
textColorFlg = false;
}
// 乱数を利用して0か1を生成(bgColorBlue用)
const randBg = Math.round(Math.random());
// bgColorBlueプロパティの値を表す変数をtrueで用意。
let bgColorFlg = true;
// 発生した乱数が0ならばfalseに変数。
if (randBg == 0) {
bgColorFlg = false;
}
// それぞれのプロパティの値をオブジェクトにして返す。
return {
textColorRed: textColorFlg,
bgColorBlue: bgColorFlg
}
});
</script>
<template>
<p v-bind:class="{ textColorRed: true, bgColorBlue: true }">{{ msg }}</p>
<p v-bind:class="{ textColorRed: isTextColorRed, bgColorBlue: isBgColorBlue }">{{ msg }}</p>
<!-- textColorPinkではCSSは適用されない -->
<p v-bind:class="{ textColorPink: true }">{{ msg }}</p>
<!-- クラス名をプロパティに指定する場合は、''で囲む -->
<p v-bind:class="{ 'text-color-pink': true }">{{ msg }}</p>
<!-- v-bind:classはclass属性と併用できる -->
<p class="textSize24" v-bind:class="{ textColorRed: isTextColorRed, bgColorBlue: isBgColorBlue }">{{ msg }}</p>
<!-- オブジェクトの指定も可能 -->
<p class="textSize24" v-bind:class="styles">{{ msg }}</p>
<!-- 算出プロパティの指定も可能 -->
<p v-bind:class="computedStyles">{{ msg }}</p>
</template>
<style scoped>
.textColorRed {
color: red;
}
.text-color-pink {
color: pink
}
.bgColorBlue {
background-color: blue;
}
.textSize24 {
font-size: 24px;
}
</style>
(): { textColorRed: boolean; bgColorBlue: boolean; }:(コロン)の右側は、この関数の戻り値を表す。
{
プロパティ名: データ型;
}このようにすることで戻り値オブジェクトのプロパティとその型が保証できる。
レンダリング結果は以下。
<p data-v-7a7a37b1="" class="textColorRed bgColorBlue">クラス属性へバインディング</p>
<p data-v-7a7a37b1="" class="textColorRed">クラス属性へバインディング</p>
<!-- textColorPinkではCSSは適用されない -->
<p data-v-7a7a37b1="" class="textColorPink">クラス属性へバインディング</p>
<!-- クラス名をプロパティに指定する場合は、''で囲む -->
<p data-v-7a7a37b1="" class="text-color-pink">クラス属性へバインディング</p>
<!-- v-bind:classはclass属性と併用できる -->
<p data-v-7a7a37b1="" class="textSize24 textColorRed">クラス属性へバインディング</p>
<!-- オブジェクトの指定も可能 -->
<p data-v-7a7a37b1="" class="textSize24 bgColorBlue">クラス属性へバインディング</p>
<!-- 算出プロパティの指定も可能 -->
<p data-v-7a7a37b1="" class="textColorRed bgColorBlue">クラス属性へバインディング</p>