Vue3のv属性を活用しよう
こんにちはあっくんです。ここ数日間、大雨で気温も下がっていましたが、昨日あたりから急に気温が上昇しています。皆さん体調は大丈夫でしょうか?水分補給と睡眠をきっちりとって、脳を万全にして勉強していきましょう。
今回はv属性についてやっていきましょう。
v属性について
Vue3のアプリケーション・オブジェクト内から利用するために「v属性」と呼ばれるものが用意されています。これは、vで始まるVue3独自の属性です。
v-○○=値
このように記述することで、独自の設定を行うことができるのです。
属性の値にバインドする。
タグ属性に、Vue3で用意した値を設定するときに用意されているの「v-bind」という属性です。
v-bind: 属性名 = "設定する値"
v-bindをつけると、属性の値はJavaScriptの式として扱われるようになるのです。
テキストサイズを設定しよう
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p v-bind:style="style">{{message}}</p>
    </div>
    <script>
      const appdata = {
        data() {
          return {
            message: null,
            style: "font-size:32pt; color:red;",
          };
        },
        mounted() {
          this.message = "This is sample page.";
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml)
v-bind:styleにより、style属性に設定されて、テキストと色が変更されました。
※v-bindは省略できる。
属性名の前に、コロン(:)をつけるだけで、自動的にv-bindが設定されていると判断してくれます。
オブジェクト構文について
v-bind:classではオブジェクト構文と呼ばれています。
↓のように記述します。
v-bind:class="{クラス名 : 変数}"
red/blueのクラスを切り替える
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <style>
      .red {
        font-style: 32px;
        font-weight: plain;
        font-style: normal;
        color: red;
      }
      .blue {
        font-size: 24px;
        font-weight: bold;
        font-style: italic;
        color: blue;
      }
      .top_back {
        background: url(./images/19_0418_13.jpg) center center fixed;
        height: 300px;
        background-size: cover;
      }
    </style>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p v-bind:class="{red:isRed, blue:isBlue}">{{message}}</p>
    </div>
    <script>
      const appdata = {
        data() {
          return {
            message: null,
            isRed: true,
            isBlue: false,
          };
        },
        mounted() {
          this.message = "This is sample page.";
          setInterval(() => {
            this.isBlue = !this.isBlue;
            this.isRed = !this.isRed;
          }, 1000);
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml)
redとblueの2つのCSSクラスが交互に設定されます。
クラス切り替えの仕組み
<style>を使って、red,blueの2つのクラスを用意しています。
<p v-bind:class="{red:isRed, blue:isBlue}">
v-bind:classには複数のクラスの指定を記述することができます。
Vueオブジェクトに設定する変数dataには↓のように値が用意されています。
data() {
  return {
     message: null,
     isRed: true,
     isBlue: false
  }
},Code language: JavaScript (javascript)isRedとisBlueを用意し、それぞれtrue,falseを指定してあります。この初期状態で、redがON,blueがOFFになっています。そして、setIntervalに用意した関数の処理は↓のようになっています。
() => {
  this.isBlue = !this.isBlue
  this.isRed = !this.isRed
}Code language: JavaScript (javascript)!を使って、data.isRedとdata.isBlueの値を反転して再設定しています。つまり、trueならばfalse,
falseならtureに変更されるようにしています。これで、redとblueのクラスが、それぞれON/OFFにされるようになります。
v-bind:classにオブジェクトを設定する
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <style>
      .red {
        font-style: 32px;
        font-weight: plain;
        font-style: normal;
        color: red;
      }
      .blue {
        font-size: 24px;
        font-weight: bold;
        font-style: italic;
        color: blue;
      }
    </style>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p v-bind:class="classes">{{message}}</p>
    </div>
    <script>
      var classObj = {
        red: true,
        blue: false,
      };
      const appdata = {
        data() {
          return {
            message: "This is sample page.",
            classes: classObj,
          };
        },
        mounted() {
          setInterval(() => {
            this.classes.red = !classObj.red;
            this.classes.blue = !classObj.blue;
          }, 1000);
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml)
動作は先程のコードと全く同じです。
オブジェクト操作の仕組み
classesだけです。このclassesに使われるオブジェクトは↓のように作成されます。
var classObj = {
  red: true,
blue: false
}Code language: JavaScript (javascript)redとblueのプロパティがあり、それぞれの真偽値が設定されています。オブジェクトをv-bind:classに指定する場合は、クラス名をそのままプロパティとして用意します。用意されたclassObjは、appdata内に用意されているdataメソッドで↓のように使われます。
data () {
  return {
     message : 'This is sample page.',
     classes : classObj
  }
}Code language: JavaScript (javascript)これで、classesという名前でclassObjがアプリケーション・オブジェクトに用意されます。後は、タイマーで実行される関数の中で、classObjを更新すれば、クリックで表示を変更できるようになります。
setInterval(() => {
  this.classes.red = !classObj.red;
  this.classes.blue = !classObj.blue;
}, 1000)Code language: JavaScript (javascript)スタイルとオブジェクト構文
「style」属性一つの属性内に多数の値を用意します。
v-bind:style="オブジェクト構文"
style属性はスタイル名と値を必要なだけ記述していきます。
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <style>
      .red {
        font-style: 32px;
        font-weight: plain;
        font-style: normal;
        color: red;
      }
      .blue {
        font-size: 24px;
        font-weight: bold;
        font-style: italic;
        color: blue;
      }
    </style>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p v-bind:style="{fontSize: '20pt',color:'red',border:'2px solid cyan'}">
        {{message}}
      </p>
    </div>
    <script>
      var classObj = {
        red: true,
        blue: false,
      };
      const appdata = {
        data() {
          return {
            message: "This is sample page.",
            classes: classObj,
          };
        },
        mounted() {
          setInterval(() => {
            this.classes.red = !classObj.red;
            this.classes.blue = !classObj.blue;
          }, 1000);
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml)
これでタグにスタイル設定された状態で表示されます。
オブジェクト構文をチェック
プロパティはハイフン後の文字を大文字します。
例、 font-size => fontSize
値は基本的にシングルクォーテーションでくくって記述します。
例、color: red => color: ‘red’
v-bind:styleにオブジェクトを指定する
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p v-bind:style="styles">{{message}}</p>
    </div>
    <script>
      const appdata = {
        data() {
          return {
            message: "This is sample page.",
            styles: {
              margin: "10px",
              padding: "5px 20px",
              fontSize: "20pt",
              color: "red",
              backgroundColor: "#fee",
              border: "3px solid blue",
            },
          };
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml)
stylesに必要なスタイル情報をまとめたオブジェクトを用意します。
data() {
  return {
    message: "This is sample page.",
      styles: {
       margin: "10px",
       padding: "5px 20px",
       fontSize: "20pt",
       color: "red",
       backgroundColor: "#fee",
       border: "3px solid blue",
    }
  }
}Code language: JavaScript (javascript)v-ifによる条件付きレンダリング
if構文に相当するのが「v-if」です。
<タグ v-if=”条件”>……表示内容…….
v−elseもあります
<タグ v-else>……表示内容…….
条件によって表示を切り替える
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <style>
      .ok {
        font-size: 24pt;
        color: blue;
        padding: 5px 10px;
        border: 2px solid red;
      }
      .ng {
        font-size: 20pt;
        color: gray;
      }
    </style>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p v-if="flag" class="ok">{{message}}</p>
      <p v-else class="ng">※現在、問題が発生中です・・・・・・</p>
    </div>
    <script>
      const appdata = {
        data() {
          return {
            message: "This is sample page.",
            flag: true,
          };
        },
        mounted() {
          setInterval(() => {
            this.flag = !this.flag;
          }, 1000);
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml)
1秒毎に2つの表示が切り替わります。
複雑な表示はtemplateタグ
<template>タグはVue3に用意されています。この<template>タグは複数のタグを1つのテンプレートとしてまとめるのに用いられます。このタグ自身は表示されません。
テーブルとリストを切り替える
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <template v-if="flag">
        <p>※データをテーブル表示する</p>
        <table class="table">
          <thead class="thead-dark">
            <tr>
              <th>Name</th>
              <th>mail</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>Taro</td>
              <td>taro@yamada</td>
            </tr>
            <tr>
              <td>Hanako</td>
              <td>hanako@flower</td>
            </tr>
            <tr>
              <td>Sachiko</td>
              <td>sachiko@happy</td>
            </tr>
          </tbody>
        </table>
      </template>
      <template v-else>
        <p>※データをリスト表示する</p>
        <ul class="list-group">
          <li class="list-group-item">Taroのアドレスは、taro@yamadaです。</li>
          <li class="list-group-item">
            hanakoのアドレスは、hanako@flowerです。
          </li>
          <li class="list-group-item">
            Sachikoのアドレスは、sachiko@happyです。
          </li>
        </ul>
      </template>
    </div>
    <script>
      const appdata = {
        data() {
          return {
            flag: true,
          };
        },
        mounted() {
          setInterval(() => {
            this.flag = !this.flag;
          }, 4000);
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml)
アクセスするとテーブルが表示されます。4秒経過するとリストに切り替わります。
<template v-if>で条件となるflagがtrueの表示を用意し、<template v-else>でflagがfalseの場合を用意します。
データをテーブル出力する
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p>{{message}}</p>
      <table class="table">
        <thead class="table-dark">
          <tr>
            <th>Name</th>
            <th>mail</th>
            <th>tel</th>
          </tr>
        </thead>
        <tr v-for="item in items">
          <td>{{item.name}}</td>
          <td>{{item.mail}}</td>
          <td>{{item.tel}}</td>
        </tr>
      </table>
    </div>
    <script>
      const appdata = {
        data() {
          return {
            message: "※データをテーブル表示する",
            items: [
              { name: "Taro", mail: "taro@yamada", tel: "999-999" },
              { name: "Hanako", mail: "hanako@flower", tel: "888-888" },
              { name: "Sachiko", mail: "sachiko@happy", tel: "777-777" },
              { name: "Jiro", mail: "jiro@change", tel: "666-666" },
            ],
          };
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml)
↑データをまとめて表示します。
データをテーブルに展開する流れ
data変数のなかにitemsというプロパティを用意し、そこにデータをまとめてあります。
items: [
  { name: "Taro", mail: "taro@yamada", tel: "999-999" },
  { name: "Hanako", mail: "hanako@flower", tel: "888-888" },
  { name: "Sachiko", mail: "sachiko@happy", tel: "777-777" },
  { name: "Jiro", mail: "jiro@change", tel: "666-666" },
]Code language: JavaScript (javascript)itemsは配列になっていまして、配列の各要素はオブジェクトになっています。そのオブジェクトにはname,mail,telといったプロパティが用意されています。これを表示しているのが↓になります。
<tr v-for="item in items">
          <td>{{item.name}}</td>
          <td>{{item.mail}}</td>
          <td>{{item.tel}}</td>
        </tr>Code language: HTML, XML (xml)tr v-for=”item in items”で、itemsの配列から順にオブジェクトを取り出し、変数itemに代入します。
インデックス番号の取得
v-forは基本的に「配列から順に要素を取り出す」という形の繰り返しです。v-forでは配列のインデックス番号を第2引数として取り出すことができます。
<タグ v-for=”(要素, インデックス) in 配列 “>
インデックス番号を表示しよう
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p>{{message}}</p>
      <table class="table">
        <thead class="table-dark">
          <tr>
            <th>ID</th>
            <th>Name</th>
            <th>mail</th>
            <th>tel</th>
          </tr>
        </thead>
        <tr v-for="(item, id) in items">
          <td>{{id}}</td>
          <td>{{item.name}}</td>
          <td>{{item.mail}}</td>
          <td>{{item.tel}}</td>
        </tr>
      </table>
    </div>
    <script>
      const appdata = {
        data() {
          return {
            message: "※データをテーブル表示する",
            items: [
              { name: "Taro", mail: "taro@yamada", tel: "999-999" },
              { name: "Hanako", mail: "hanako@flower", tel: "888-888" },
              { name: "Sachiko", mail: "sachiko@happy", tel: "777-777" },
              { name: "Jiro", mail: "jiro@change", tel: "666-666" },
            ],
          };
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml)
↑IDとして、各要素のインデックス番号を表示するようになりました。
オブジェクトをv-forする場合
<タグ v-for=”(値, キー) in オブジェクト”>
()の部分には、オブジェクトから取り出した値とそのキーが取り出されます。
オブジェクトをテーブル化する
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p>{{message}}</p>
      <table class="table">
        <thead class="table-dark">
          <tr>
            <th>Name</th>
            <th>mail</th>
            <th>tel</th>
          </tr>
        </thead>
        <tr v-for="(item, key) in items">
          <td>{{key}}</td>
          <td>{{item.mail}}</td>
          <td>{{item.tel}}</td>
        </tr>
      </table>
    </div>
    <script>
      const appdata = {
        data() {
          return {
            message: "※データをテーブル表示する",
            items: {
              Taro: { mail: "taro@yamada", tel: "999-999" },
              Hanako: { mail: "hanako@flower", tel: "888-888" },
              Sachiko: { mail: "hanako@flower", tel: "888-888" },
              Jiro: { mail: "jiro@change", tel: "666-666" },
            },
          };
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml) 
↑itemsオブジェクトの中身がテーブル表示されています。
違いは「データの順序」
すべてのキーはユニークである
「ユニーク」とは「同じ値が複数存在しないこと」です。オブジェクトの場合はユーザーの名前をプロパティにして、その人のユーザー情報を保管していました。つまり、「同じ名前の人は、複数保管できない。」ということになります。
値の並び順は保証されない
配列の場合はインデックス番号の順に値は取り出されました。オブジェクトは順番が指定されているわけではありません。つまり、オブジェクトでは、「こういう順番で取り出す」ということができません。
v-forとv-ifを組み合わせる
v-forを使ってテーブルを表示させる際、更にv-ifで条件に応じて表示を変更させることもできます。
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p>{{message}}</p>
      <table class="table">
        <thead class="table-dark">
          <tr>
            <td>ID</td>
            <th>Name</th>
            <th>mail</th>
            <th>tel</th>
          </tr>
        </thead>
        <template v-for="(item, index) in items">
          <tr v-if="index % 2 == 0">
            <td>{{index}}</td>
            <td>{{item.name}}</td>
            <td>{{item.mail}}</td>
            <td>{{item.tel}}</td>
          </tr>
          <tr v-else>
            <td>***</td>
            <td>***非公開***</td>
            <td>***非公開***</td>
            <td>***非公開***</td>
          </tr>
        </template>
      </table>
    </div>
    <script>
      const appdata = {
        data() {
          return {
            message: "※データをテーブル表示する",
            items: [
              { name: "Taro", mail: "taro@yamada", tel: "999-999" },
              { name: "Hanako", mail: "hanako@flower", tel: "888-888" },
              { name: "Sachiko", mail: "sachiko@happy", tel: "777-777" },
              { name: "Jiro", mail: "jiro@change", tel: "666-666" },
              { name: "Mami", mail: "mami@change", tel: "555-555" },
            ],
          };
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml) 
v-for,v-ifをチェックする
v-for=”(item, index) in items”が優先され、itemsから順番にインデックス番号が(item, index)に取り出されています。その内部でv-if=”index % 2 == 0″がチェックされます。これがtrueならこのタグが表示されます。falseなら、v-elseのタグが表示されます。
<template>をフル活用しよう
レンダリングされると消えてしまう<template>を利用することでv-属性を整理しやすくなります。
<!DOCTYPE html>
<html>
  <head>
    <title>My first Vue app</title>
    <!-- CSS only -->
    <link
      href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css"
      rel="stylesheet"
      integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1"
      crossorigin="anonymous"
    />
    <!-- JavaScript Bundle with Popper -->
    <script
      src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js"
      integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW"
      crossorigin="anonymous"
    ></script>
    <script src="https://unpkg.com/vue@next"></script>
  </head>
  <body>
    <h1 class="bg-secondary text-white display-4 px-3">Vue3</h1>
    <div id="app" class="container">
      <p>{{message}}</p>
      <table class="table">
        <thead class="table-dark">
          <tr>
            <td>ID</td>
            <th>Name</th>
            <th>mail</th>
            <th>tel</th>
          </tr>
        </thead>
        <template v-for="(item, index) in items">
          <template v-if="index % 2 == 0">
            <tr>
              <td>{{index}}</td>
              <td>{{item.name}}</td>
              <td>{{item.mail}}</td>
              <td>{{item.tel}}</td>
            </tr>
          </template>
          <template v-else>
            <tr>
              <td>***</td>
              <td>***非公開***</td>
              <td>***非公開***</td>
              <td>***非公開***</td>
            </tr>
          </template>
        </template>
      </table>
    </div>
    <script>
      const appdata = {
        data() {
          return {
            message: "※データをテーブル表示する",
            items: [
              { name: "Taro", mail: "taro@yamada", tel: "999-999" },
              { name: "Hanako", mail: "hanako@flower", tel: "888-888" },
              { name: "Sachiko", mail: "sachiko@happy", tel: "777-777" },
              { name: "Jiro", mail: "jiro@change", tel: "666-666" },
              { name: "Mami", mail: "mami@change", tel: "555-555" },
            ],
          };
        },
      };
      let app = Vue.createApp(appdata);
      app.mount("#app");
    </script>
  </body>
</html>
Code language: HTML, XML (xml)
v属性はtemplateを使って記述し管理するほうが構造的にもわかりやすいと思います。
ここまで読んでいただいてありがとうございます。
掌田津耶乃さんのVue.js3超入門で勉強をしています。語りかけるような文章ですごいわかりやすいです。
 
				