Vue.js

#4 Vue.js基礎(v-model、その他のデータバインディングのディレクティブ)

kurumin

双方向データバインディングを実現するv-model

<script setup lang="ts">
import { ref } from "vue";

const inputNameModel = ref("双方向");
</script>

<template>
  <input type="text" v-model="inputNameModel"><br>
  <p>{{ inputNameModel }}</p>
</template>

入力欄の文字を変更するとその下の文字も入力した内容に変化する。

v-bind:valueとv-on:inputの組み合わせ

<script setup lang="ts">
import { ref } from "vue";

const inputName2Way = ref('双方向');
const onInputName2Way = (event: Event): void => {
  const element = event.target as HTMLInputElement;
  inputName2Way.value = element.value;
}
</script>

<template>
  <input type="text" v-bind:value="inputName2Way" v-on:input="onInputName2Way"><br>
  <p>{{ inputName2Way }}</p>
</template>

v-bind:valuev-on:inputを組み合わせると双方向バインディングが完成する。

様々な入力コントロール

<script setup lang="ts">
import { ref } from "vue";

const inputTextarea = ref("テキストエリア\n改行");
const memberType = ref(1);
const memberTypeSelect = ref(1);
const isAgreed = ref(false);
const isAgreed01 = ref(0);
const selectedOS = ref([]);
const selectedOSSSelect = ref([]);
</script>

<template>
  <textarea v-model="inputTextarea"></textarea><br>
  <section>
    <label><input type="radio" name="memberType" value="1" v-model="memberType">通常会員</label>
    <label><input type="radio" name="memberType" value="2" v-model="memberType">特別会員</label>
    <label><input type="radio" name="memberType" value="3" v-model="memberType">優良会員</label>
    <p>選択されたラジオボタン:{{ memberType }}</p>
  </section>

  <section>
    <select v-model="memberTypeSelect">
      <option value="1">通常会員</option>
      <option value="2">特別会員</option>
      <option value="3">優良会員</option>
    </select>
    <p>選択されたリスト:{{ memberTypeSelect }}</p>
  </section>

  <section>
    <label><input type="checkbox" v-model="isAgreed">同意する</label>
    <p>同意の結果:{{ isAgreed }}</p>
  </section>

  <section>
    <label><input type="checkbox" v-model="isAgreed01" true-value="1" false-value="0">同意する</label>
    <p>同意の結果:{{ isAgreed01 }}</p>
  </section>

  <section>
    <label><input type="checkbox" v-model="selectedOS" value="1">macOS</label>
    <label><input type="checkbox" v-model="selectedOS" value="2">Windows</label>
    <label><input type="checkbox" v-model="selectedOS" value="3">Linux</label>
    <label><input type="checkbox" v-model="selectedOS" value="4">iOS</label>
    <label><input type="checkbox" v-model="selectedOS" value="5">Android</label>
    <p>選択されたOS:{{ selectedOS }}</p>
  </section>

  <section>
    <select v-model="selectedOSSSelect" multiple>
      <option value="1">macOS</option>
      <option value="2">Windows</option>
      <option value="3">Linux</option>
      <option value="4">iOS</option>
      <option value="5">Android</option>
    </select>
    <p>選択されたOS:{{ selectedOSSSelect }}</p>
  </section>
</template>

その他のデータバインディングのディレクティブ

HTML文字列をタグとして出力するv-html

<script setup lang="ts">
import { ref } from "vue";

const htmlStr = ref(`<a href="https://vuejs.org/">Vue.js<a/>`)
</script>

<template>
  <p><b>マスタッシュ構文で出力</b></p>
  <p>{{ htmlStr }}</p>
  <p><b>v-htmlを使用して出力</b></p>
  <p v-html="htmlStr"></p>
</template>

v-htmlディレクティブはHTML文字列をそのまま埋め込むため、クロスサイトスクリプティングの脆弱性を含んでしまう可能性がある。v-htmlを利用して表示するのは信用できるものに限定する。

静的コンテンツとして表示させるv-pre

<template>
  <section v-pre>
    <p v-on:click="showHello">{{ hello! }}</p>
  </section>
</template>

データバインドを一度だけ行うv-once

<script setup lang="ts">
import { ref } from "vue";

const price = ref(1000);
</script>

<template>
  <input type="number" v-model="price">円<br>
  <p>金額は{{ price }}円です。</p>
  <p v-once>金額は{{ price }}円です。</p>
</template>

最初の一回だけデータバインドを行う。

レンダリング終了までマスタッシュ構文を非表示にするv-cloak

テンプレート構文に記述されたマスタッシュ構文は、HTMLが読み込まれたあとにJavaScriptいよって値が埋め込まれる。ということは、場合によっては値が埋め込まれるまでの一瞬の間にマスタッシュ構文がそのまま表示されてしまうことがある。

これを防ぎたい場合に、v-cloak構文を利用する。

<script setup lang="ts">
import { ref } from "vue";

const hello = ref("こんにちは");
</script>

<template>
  <p v-cloak>{{ hello }}</p>
</template>

<style>
[v-cloak] {
  display: none;
}
</style>

v-cloakディレクティブは、最初は属性としてそのままレンダリングされるが、マスタッシュ構文のレンダリングが終了したタイミングでVueによって取り除かれる。

この仕組みを利用して、v-cloak属性の付いたタグにdisplay: none;を適用すれば、レンダリング途中でマスタッシュ構文が表示されるのを防ぐことができる。

ABOUT ME
記事URLをコピーしました