【Vue.js】Vue.jsって何だろう（基本な操作（v-if/v-else-if/v-else・v-show・v-for）編）

## 1.はじめに
今回は、第二弾でVue.jsの基本的な操作のうちhtml部分に記述する部分をいくつかまとめていきます。
第一弾は[こちら](https://qiita.com/kari_account/items/7c0f6b0e453c168ef11c)

## 2.基本的な書き方
### 概要
``` javascript

<template>
　// 今回はここに書くことをまとめていきます。
     // htmlに書くこと（画面に表示するもの）を記述
</template>

<script>
     // javascriptに書くこと（関数など）を設定
</script>

<style>
    // cssに書くこと（文字の色・大きさなどのデザイン）を記述
</style>
```

## 3.基本的な操作

### ①v-if/v-else-if/v-else
条件に応じてHTMLの表示・非表示を切り替えることが出来るコードです。


** ＜基本的な書き方＞ **
v-ifは””内の条件が「true」のときだけ表示するコードです。

``` javascript
<p v-if="条件">この文章は条件がtrueのときだけ表示されます</p>
``` 

v-else-ifやv-elseはv-if内がfalseだった場合の表示を書くことができます。

``` javascript
<p v-if="条件①">この文章は条件①がtrueのときに表示されます</p>
<p v-else-if="条件②">この文章は条件①がfalseで条件②がtrueのときに表示されます</p>
<p v-else>この文章は条件①・条件②どちらもfalseの時に表示されます</p>
``` 

:ok: 
``` javascript
<p v-if="ok">はい</p>
<p v-else-if="close">惜しい</p>
<p v-else>いいえ</p>
``` 

:ng: : 
``` javascript
<p v-if="ok">はい</p>

<p v-else-if="close">惜しい</p>
<!-- 空行やコメントなど入れるとエラーの原因になります -->
<p v-else>いいえ</p>
``` 

** ＜テストコード＞ **
``` javascript
<template>
    <!-- 表示切り替え部分 -->
    <p v-if="isAdmin">管理者としてログインしています</p>
    <p v-else-if="isLoggedIn">一般ユーザーとしてログインしています</p>
    <p v-else>ログインしていません</p>

    <!-- 状態切り替えボタン -->
    <div>
    <button @click="loginAsUser">ユーザーとしてログイン</button>
    </div>
  <br>
  <div>
    <button @click="loginAsAdmin">管理者としてログイン</button>
    </div>
    <br>
  <div>
    <button @click="logout">ログアウト</button>
  </div>
</template>

// ここは次回以降説明します。
<script>
  export default {
      data() {
        return {
          isLoggedIn: false,
          isAdmin: false
        };
      },
      methods: {
        loginAsUser() {
          this.isLoggedIn = true;
          this.isAdmin = false;
        },
        loginAsAdmin() {
          this.isLoggedIn = true;
          this.isAdmin = true;
        },
        logout() {
          this.isLoggedIn = false;
          this.isAdmin = false;
        }
      }
}
</script>
``` 

最初に表示したときにはisLoggedInもisAdminもfalseのため、v-else内の「ログインしていません」が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/61ed4033-829f-4c82-9d1d-674b18bc46ea.png)

次に「ユーザーとしてログイン」ボタンを押すと、isLoggedInのみtrueになるため、v-else-if内の「一般ユーザーとしてログインしています」が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/1eba6eb5-0806-4803-98c5-40dc2e247aa0.png)


次に「管理者としてログイン」ボタンを押すとisAdminもtrueになるため、v-if内の「管理者としてログインしています」が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/857dd5fe-d46f-49e2-8149-0083f170ffcc.png)


最後に「ログアウト」ボタンを押すとisAdminもfalseになるため、v-else内の「ログインしていません」が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/7b96a58c-0d77-47d2-a8a9-86ba9b9d0322.png)

### ②v-show
v-showはv-ifと同様htmlの要素を表示・非表示にするためのコードです。

<b>＜基本的な書き方＞ </b>

``` javascript
 <p v-show="条件">この文章は条件がtrueのときだけ表示されます</p>
``` 

<b> ＜v-ifとの違い＞ </b>
v-ifとの違いは要素を非表示に切り替える際に要素が存在するかしないかの違いになります。

v-if : 要素を<b>実際に出したり消したり </b>する
v-show: 要素はずっとあるがcssで<b>見えなくする </b>だけ

v-showの場合要素を見えなくするだけのため、v-ifで切り替える場合よりも処理速度が速いという特徴があります。
→表示の切り替えが多いときにお勧めです。

少しわかりづらいかもしれないので、演劇に例えて説明してみます。

### 🧍‍♂️ v-if：必要なときだけ「人を呼ぶ」
たとえば舞台の演劇で、あるシーンになったら「役者Aさん登場！」と舞台袖から呼んできます。
シーンが終わったらまた退場して、いなくなります。

登場するとき → 舞台に「出てくる」
いないとき → 本当に「いない」

これが v-if の動きです。
見えないときは<b>完全に</b>存在しません。

### 👻 v-show：カーテンで「隠すだけ」
今度は役者さんはずっと舞台上にいます。
でも「見せないとき」はカーテンやライトで見えなくしてるだけ。

見せるとき → カーテンを開ける
見せないとき → カーテンを閉める（いるけど見えない）

これが v-show の動きです。
見えなくても<b>実はずっとそこ</b>にいます。

実際のコードで見ていきましょう

＜テストコード＞
``` javascript
<template>
    <h2>v-ifとv-show 比較</h2>

    <div>
    <!-- 切り替えボタン -->
    <button @click="visible = !visible">
      表示切り替え（現在：{{ visible ? '表示中' : '非表示' }})
    </button>
    </div>
   
    <br>
    <!-- v-if を使ったブロック -->
    <div v-if="visible" class="box">
      <strong>これは v-if で表示されています</strong>
    </div>
    <br>
  
    <!-- v-show を使ったブロック -->
    <div v-show="visible" class="box">
      <strong>これは v-show で表示されています</strong>
    </div>
</template>

// ここは次回以降説明します。
<script>
  export default {
      data() {
           return {
          visible: true
        };
      }
 }
</script>
```

これを実行しWindowsだとctrl+shift+iキーを同時押しして、デベロッパーツールを開き、elementsから要素の確認をすると以外がよくわかります。

条件がtrueの場合は
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/7f931cd9-8556-4f36-90d0-248bf40aa7ca.png)

どちらも要素は表示されますが、

表示切り替えボタンを押し、非表示にすると、
v-ifで囲んだところは、要素が消えていますが、v-showで囲んだところはstyle="display: none;"が追加されるのみでv-show自体は残っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/6baf1d0f-c080-4735-9120-ddb30112375e.png)

### ③v-for
v-forはリストを繰り返し表示するコードです

**＜説明＞**
下のリストを箇条書きで表示したいと考えています。

箇条書きのリストをHTMLで書こうとしたとき、下記のように表示します。

``` javascript
<ul>
  <li>りんご</li>
  <li>みかん</li>
  <li>バナナ</li>
</ul>
``` 

ただし、箇条書きに表示したい項目数が増えたり変更があった時にいちいち確認して修正するのは面倒です・・・

そこで、v-forで表示することで、配列に要素を追加しておけば、Vueが配列を読み取り、リストの中身の個数分、自動で <li> を繰り返し出力してくれるようになります。

``` javascript
data() {
  return {
   // この配列に要素を追加するだけで
    fruits: ['りんご', 'みかん', 'バナナ']
  }
}
``` 

``` 
<ul>
 // この中身は変えなくても変更が反映されるようになります。
  <li v-for="fruit in fruits">{{ fruit }}</li>
</ul>
``` 

・りんご
・みかん
・バナナ

また、下記のように書くと、

```  javascript
  <ul>
      <div v-for="(fruit, index) in fruits">
        {{ index + 1 }}. {{ fruit }}
  	   </div>
  </ul>
``` 

その値が**何番目であるか**も取得・表示することが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/08c38d4d-2a68-4717-893f-adf79c21e4de.png)

** ＜基本的な書き方＞ **
``` javascript
　// 例  <p v-for="fruit in fruits"></p>
     <p v-for="リストの中身 in 配列"></p>

     // リストの中身が何番目かも知りたい場合は下記のように書きます。（0番目から始まります。）
　// 例  <p v-for="(fruit, index) in fruits"></p>
     <p v-for="(リストの中身, リストの中身が何番目かの値) in 配列"></p>

     //  Vueにリストの中身が何番目かの情報を記憶させたい場合は:keyを指定します。
    // 例 <p v-for="(fruit, index) in fruits" :key="index"></p>
   <p v-for="(リストの中身, リストの中身が何番目かの値) in fruits" :key="リストの中身が何番目かの値"></p>
    
``` 

＜テストコード＞
``` javascript
<template>
    <h2>好きな果物リスト</h2>
    <ul>
      <li v-for="fruit in fruits">{{ fruit }}</li>
    </ul>
     
  	<ul>
      <div v-for="(fruit, index) in fruits">
        {{ index + 1 }}. {{ fruit }}
  	   </div>
  	</ul>
</template>

// ここは次回以降説明します。
<script>
  export default {
    data() {
      return {
        fruits: ['りんご', 'みかん', 'バナナ']
      };
    },
 }
</script>
``` 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/f80a0e21-becc-40b0-912c-92c07865bc09.png)

fruits: ['りんご', 'みかん', 'バナナ']の最後にももを追加して、 fruits: ['りんご', 'みかん', 'バナナ','もも']のようにすると、画面にもももが追加されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/5d04ea57-3d7a-4856-b7e7-91d6b2b10f9a.png)

``` javascript
<template>
    <div v-for="fruit in fruits">
      <div>{{ fruit }}</div>
      <input type="text" />
    </div>
  
   <br>
   <br>
    <div v-for="fruit in fruits" :key="fruit">
      <div>{{ fruit }} キー指定ver</div>
      <input type="text" />
    </div>
  <br>
  <button @click="remove">先頭のテキストボックスを削除</button>
</template>

// ここは次回以降説明します。
<script>
  export default {
    data() {
      return {
        fruits: ['りんご', 'みかん', 'バナナ']
      };
    },
    methods: {
      remove: function () {
        this.fruits.shift();
      },
    },
 }
</script>
``` 

また、上記のテストコードを書いたうえで、それぞれの入力欄に何かしら入力後、「先頭のテキストボックスを削除」ボタンを押した場合に、キーを指定していない方の入力欄の値が変わらない現象が起こります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/58c2b38b-bd13-43f3-98f3-13ca432068e6.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3762100/f50ce79f-0750-4f76-84d2-d89a1f091b63.png)


それは、Vueが変化したところのみを検知して表示する（位置が変わらない部分はそのままにする）という性質があるためです。そのために、1番目と2番目の値は変化なしとして変更しない現象が起こります。

:key のプロパティをつけることで、**どの入力欄がfruitのこの値とペアだよ**と通知されることで「fruitの値が変わったら、古いinputを使いまわさずに作り直そう」となり、期待した挙動になります。
ですので基本的に:keyプロパティはつけておくのが無難です。

## 4.さいごに
今回はv-if/v-else-if/v-else・v-show・v-forを紹介しました。
次回以降はscriptタグ内に書くことをまとめていきたいと思います。