【Vue】Vue ~ 基本編:ディレクティブ ~

■ はじめに

https://dk521123.hatenablog.com/entry/2020/04/30/000000

の続き。

 今回は、サンプルを交えながら、
ディレクティブ(v-から始まる)の
基本的な書き方を学ぶ。

目次

【1】v-text / v-html
【2】v-model / v-bind
【3】v-if / v-show
 補足:v-if vs v-show
【4】v-on
 補足:省略した書き方(e.g v-on:click => @click)
【5】v-for

【1】v-text / v-html

1)v-text

* テキストとして表示する
 => HTMLタグもそのまま表示

2)v-html

* HTMLとして表示する
 => HTMLタグを指定すれば、そのまま適用する

サンプル

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello world</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <!-- ★HTML部分★ -->
  <div id="app">
    <!-- 「<b>Hello world!</b>」が表示 -->
    <div><p v-text="value1"></p></div>
    <!-- 「Hello <b>Hello world!!</b>」が表示 -->
    <div><p>Hello {{value2}}</p></div>
    <!-- 「Hello world!!!」(太文字)が表示 -->
    <div><p v-html="value3"></p></div>
  </div>
  <script>
    <!-- ★JS部分★ -->
    var app = new Vue({
      el: '#app',
      data: {
        value1: '<b>Hello world!</b>',
        value2: '<b>Hello world!!</b>',
        value3: '<b>Hello world!!!</b>',
      }
    });
  </script>
</body>
</html>

【2】v-model / v-bind

* バイディング

1)v-model

* 双方向(インタラクティブ)データバインディング
 => 以下のサンプルでは、
  Vue オブジェクトのデータとフォーム部品の値が
  関係づけられる

2)v-bind

* 一方向データバインディング
* 『v-bind:[属性]="プロパティ"』で指定

サンプル

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello world</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <!-- ★HTML部分★ -->
  <div id="app">
    <div><p>v-model - textボックスを編集してみて</p></div>
    <div><p><input type="text" v-model="message1"></p></div>
    <div><p>{{ message1 }}</p></div>
    <div><p>v-bind - textボックスを編集してみて</p></div>
    <div><p><input type="text" v-bind:value="message2"></p></div>
    <div><p>{{ message2 }}</p></div>
  </div>
  <script>
    <!-- ★JS部分★ -->
    var app = new Vue({
      el: '#app',
      data: {
        message1: 'Hello, v-model!',
        message2: 'Hello, v-bind!!'
      }
    });
  </script>
</body>
</html>

【3】v-if / v-show

1)v-if / v-else-if / v-else

* 条件制御

2)v-show

* 表示 / 非表示を制御

補足:v-if vs v-show

https://jp.vuejs.org/v2/guide/conditional.html#v-if-vs-v-show

より抜粋
~~~~~~~~~~~~
とても頻繁に何かを切り替える必要があれば v-show を選び、
条件が実行時に変更することがほとんどない場合は、v-if を選びます。
~~~~~~~~~~~~

サンプル

例1:v-if / v-show / v-on

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello v-if / v-on</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <!-- ★HTML部分★ -->
  <div id="app-x">
    <div><button v-on:click="toggleMessage">Click me!</button></div>
    <div><span v-if="isShown">Now you see me</span><div>
    <div><span v-show="isShown">Now you see me!!</span><div>
  </div>
  <script>
  <!-- ★JS部分★ -->
  var app = new Vue({
    el: '#app-x',
    data: {
      isShown: false
    },
    methods: {
      toggleMessage: function () {
        console.log("onClick : " + this.isShown);
        this.isShown = !this.isShown;
      }
    }
  });
  </script>
</body>
</html>

例2:v-if / v-else-if / v-else

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello v-if / v-on</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <!-- ★HTML部分★ -->
  <div id="app-x">
    <input type="radio" id="A" value="A" v-model="picked">
    <label for="A">A</label>
    <br>
    <input type="radio" id="B" value="B" v-model="picked">
    <label for="B">B</label>
    <br>
    <input type="radio" id="C" value="C" v-model="picked">
    <label for="C">C</label>
    <br>
    <input type="radio" id="D" value="D" v-model="picked">
    <label for="D">D</label>
    <br>
    <span>Picked: {{ picked }}</span><br>
    <div>
      <div>Sample for v-if</div>
      <p v-if="picked === 'A'">A</p>
      <p v-else-if="picked === 'B'">B</p>
      <p v-else-if="picked === 'C'">C</p>
      <p v-else>Not A/B/C</p>
    </div>
  </div>
  <script>
  <!-- ★JS部分★ -->
  var app = new Vue({
    el: '#app-x',
    data: {
      picked: ''
    }
  });
  </script>
</body>
</html>

【4】v-on

v-on

* イベントを処理する

補足:省略した書き方(e.g v-on:click => @click)

よく使うので、「v-on:」⇒「@」で置き換えることが可能

<button v-on:click="countUp">Click me!</button><button @click="countUp">Click me!</button>

サンプル

<template>
  <div>
    <div>count: {{ count }}</div>
    <input type="text" v-bind:value="count" v-on:keyup="updateCount" />
    <button v-on:click="countUp">Click me!</button>
    <button v-on:click="clear">Clear</button>
  </div>
</template>

<script>
export default {
  name: "First Counter",
  data: () => ({
    count: 0,
  }),
  methods: {
    countUp() {
      this.count = this.count + 1;
    },
    clear() {
      this.count = 0;
    },
    updateCount(event) {
      this.count = event.target.value;
    },
  },
};
</script>

【5】v-for

v-for

* ループ制御

サンプル

例1:Hello World

<template>
  <div>
    <ul>
      <li v-for="item in items" :key="item.message">
        {{ item.message }}
      </li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "First Loop",
  data: () => ({
    items: [{ message: "Hello" }, { message: "World" }],
  }),
};
</script>

例2:Hello ToDo

<!DOCTYPE html>
<html lang="jp">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Hello v-for / v-model</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <!-- ★HTML部分★ -->
  <div id="app-x">
    <input v-model="message">
    <button v-on:click="saveMessage">Show me!</button>
    <ol>
      <li v-for="todo in todos">
        {{ todo.text }}
      </li>
    </ol>
  </div>
  <script>
  <!-- ★JS部分★ -->
  var app = new Vue({
    el: '#app-x',
    data: {
      todos: [
        { text: 'Hello' },
        { text: 'World' }
      ],
      message: '!!'
    },
    methods: {
      saveMessage: function () {
        console.log(this.message)
        this.todos.push({ text: this.message });
        this.message = '';
      }
    }
  });
  </script>
</body>
</html>

参考文献

https://qiita.com/hosomichi/items/25041c1d46452de84aa6

関連記事

Vue ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/04/30/000000
Vue CLI ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/12/22/192553
Vuetify ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/12/26/000242
Vue Router ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/12/24/000000