見出し画像

Vue.js勉強記録その2 -Chapter2 Vue3の基本をマスターしよう!

■2-1 Vue3の基本的な仕組み

Chapter1で最初に書いたコードを改造して、簡単なカウンター的なコードを書く。(関数doActionの記述は、なんとなくアロー関数に書き換えてみた。)

<body>
   <h1>Vue3</h1>
   <div id="app">
       <p>{{message.toUpperCase() + "[" + new Date().toLocaleString() + "]"}}</p>
       <hr>
       <button onclick="doAction();">Stop</button>
   </div>
   
   <script>
       let timer = null;
       const doAction = () => {
           clearInterval(timer);
       }
       const appdata = {
           data() {
               return {
                   message: '',
               }
           },
           created() {
               this.message = 'Hello Vue!';
               this.count = 0;
           },
           mounted() {
               timer = setInterval(() => {
                   this.count++;
                   this.message = 'Count: ' + this.count;
               }, 1000)
           }
       }
       Vue.createApp(appdata).mount('#app')
   </script>
</body>

まずは、const appdataで、必要な定数を作り、

Vue.createApp(appdata)で、アプリケーション・オブジェクトなるものを生成し、xxx.mout('#app')で、idがappのdivタグにマウントすると書かれている。

このマウントという言葉は、「取り付ける」という意味で使われると思われる。(いわゆるマウントを取るとかのマウントとは違うと思う。。)

そう考えると、要は、idがappのdivタグに、vueで作ったアプリケーション・オブジェクトを取り付けている事がわかる。

const appdataの中身は、3つのオブジェクトが書かれている。

dataメソッドが、オブジェクト内で使う値を設定する場所。
今回は、HTMLに{{message}}の記述があるから、message:''が必要になる。
マウントした#appの中に、{{count}}の表記が無いので、countはdataの中になくても良い。
なお、message:''を消してみたら、タイマーがちゃんと動かなかった。

createdメソッドは、アプリケーション・オブジェクトが生成された時に実行される処理を記述するためのものとある。mountedよりも早く実行される。初期化の際に使われる。

mountedメソッドは、Vue3オブジェクトがWebページに組み込まれた際に実行される処理を書く。


■2-2 要素と表示を考える

・v-htmlを使った出力

引き続き、色々な書き方で画面に出力していく。

{{}}だと、htmlタグを出力することが出来ないので、v-htmlを使った、htmlの出力。

<div v-html='変数名'></div>

こうすると、divタグの中に変数に格納したhtmlが出力される。

<body>
   <h1>Vue3</h1>
   <div id="app">
       <div v-html="message"></div>
   </div>

   <script>
       const list = ['One', 'Two', 'Three'];
       const appdata = {
           data() {
               return {
                   message: `<ul>
                       <li>${list[0]}</li>
                       <li>${list[1]}</li>
                       <li>${list[2]}</li>
                       `
               }
           }
       }
       let app = Vue.createApp(appdata);
       app.mount('#app');
   </script>
</body>

こう書くと、出力時に、chromeの検証ツールで見た時に、

<div id="app" data-v-app="">
    <div>
        <ul>
            <li>One</li>
            <li>Two</li>
            <li>Three</li>
        </ul>
    </div>
</div>

こんな感じになる。

dataメソッドのreturnに書かれているmessageが、「`」バックスラッシュで括られているのもポイント。${・・・}の、テンプレートリテラルの書き方になっている。


・三項演算子を使った分岐

三項演算子を、{{}}の中で使うことが出来る。

<h1>Vue3</h1>
   <div id="app">
       <div>{{num + 'は、'+(num%2==0?'偶数':'奇数')+'です'}}</div>
   </div>

   <script>
       const appdata = {
           data() {
               return {
                   num: Math.floor(Math.random() * 100)
               }
           }
       }
       let app = Vue.createApp(appdata);
       app.mount('#app');
   </script>

{{}}の中の、

num%2==0?'偶数':'奇数'

は、numが2で割り切れるかどうかで、偶数と奇数を出し分けている。


・mapによる繰り返し

配列とmapを使って繰り返し的な処理をする。

こんな感じの文法。

配列.map((value,key) => 処理)
<h1>Vue3</h1>
   <div id="app">
       <pre>
            {{data.map((value,key)=>key + ':「' + value + '」').join('\n')}}
       </pre>
   </div>

   <script>
       const data = ['Windows', 'Mac', 'Linux', 'iOS', 'Android'];
       const appdata = {
           data() {
               return {
                   data: data
               }
           }
       }
       let app = Vue.createApp(appdata);
       app.mount('#app');
   </script>

今まで、mapメソッドをほとんど使ったことが無かったので、良い勉強になった。

mapは、あくまで配列自体に処理をするものなので、forEachみたいな使い方ではないらしい。ちょっと慣れない書き方w

ここから先は、少しvue.jsを離れて、bootstrapの話が続く。
bootstrapは、ほとんど使ったことがないので、これはこれで良い復習になる。
bootstrapは、一度ちゃんとがっつり勉強したいな。そうすると、色々楽になると思う。


■2-3 v属性を活用しよう

vue.jsには、v属性なるものが用意されていて、それの使い方の説明。
ちょと前に出て来た、v-htmlもv属性の一つ。


・属性に値をバインドする

v-bindの使い方

bindには、「練る」、「結ぶ」などの意味がある。この場合は、「結ぶ」に近い使い方の様。

v-bind:属性名 = "設定する値"

の様に使う。v-bindをつけると、属性の値はjavascriptの式として扱われる。

v-bind:name = "message"

とすると、一見するとname属性の値に、文字列messageが出力されそうだが、実際は変数messageの値が出力される。


・v-bindの活用例 style属性を使う

こんな感じで書くと、<div id="app" class="container">

<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>

v-bind:style="style"の内、

v-bind:styleが、style属性になり、"style"が、font-size:32pt;color:redに置き換わる


・クラスの切り替え

class属性を付けたり消したりする時に、オブジェクト構文なるものが使える

v-bind:class ="{クラス名 : 変数}"

こう書くと、変数がtrueの時にクラスが付加され、falseの時にクラスが消される。

<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>

mounted()の中で、setIntervalを使い、isRedとisBlueに真偽値を交互に付け替えている。こうすると、pタグにはredとblueのクラスが交互に付加される。(red、blueクラスのcssの内容は省略)


ただこれだと、v-bindの中にオブジェクトを書くのが若干煩雑なので、v-bindの中のオブジェクトを変数に持たせる書き方が紹介されている。

なお、このコードは初版には誤植があります(P124のコードに間違いがあり、正誤表で訂正されている)

<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>

こうすると、変数classObjにクラス名と真偽値のセットを入れて書き、dataメソッド内のreturnするオブジェクトで、classes: classObjとする事で、v-bind:class="classes"と書くことが出来る。

また、同じ様にstyle属性をオブジェクトで持たせる記述もある。

コードは一部省略

--省略--
<p :style="styles">{{message}}</p>
--省略--
data() {
   return {
       message: 'This is sample page.',
       classes: classObj,
       styles: {
           margin: '10px',
           padding: '5px 10px',
           fontSize: '20pt',
           color: 'red',
           backgroundColor: '#fee',
           border: '3px solid blue'
       }
   }
}

個人的には、jqueryでも、直接cssの値を変える、cssメソッドは意外と使わず、classを付けて処理することが多いので、この書き方(style属性に一つ一つ値を入れる方法)は、あまり使わないのではと予測。。。


・v-ifを使って分岐

v-if属性とv-else属性を使うと分岐できる。テキストには書かれていないが、v-else-if属性もあるらしい。

なお、少し読み進めると、分岐の属性や先にある繰り返し用の属性は、divやpなど普通のhtmlタグ自体に付けることもできるが、templateタグに付けることをオススメしているし、僕もその方が見やすいと感じた。

<template v-if="条件A">
    code-A
</template>
<template v-else-if="条件B">
    code-B
</template>
<template v-else>
    code-C
</template>

こんな感じになる。


<div id="app" class="container">
   <template v-if="flag">
       <p>※データをテーブル表示する</p>
       <table class="table">
           --省略--
       </table>
   </template>
   <template v-else>
       <p>※データをリスト表示する</p>
       <ul class="list-group">
           --省略--
       </ul>
   </template>
</div>

<script>
   const appdata = {
       data() {
           return {
               message: 'This is sample page.',
               flag: true
           }
       },
       mounted() {
           setInterval(() => {
               this.flag = !this.flag;
           }, 10000);
       }
   }
   let app = Vue.createApp(appdata);
   app.mount('#app');
</script>

mountedで設定したsetIntervalが、変数flagの値を10秒ごとにtrueとfalseを切り替えて、v-if属性のあるtemplateを切り替えている。


・v-forで繰り返し

<div id="app" class="container">
   <p>{{message}}</p>
   <table class="table">
       <thead class="thead-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: 'This is sample page.',
               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>

dataメソッドで、itemsという配列を作り、v-forでtrタグを繰り返す感じ。

v-for="(item,id)の、itemには繰り返す値を順番に、idはインデックス番号が出力される。


配列ではなく、オブジェクトで繰り返す場合は、以下の様な感じ。

<div id="app" class="container">
   <p>{{message}}</p>
   <table class="table">
        --省略--
       <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: 'This is sample page.',
               items: {
                   Taro: { mail: 'taro@yamada', tel: '999-999' },
                   Hanako: { mail: 'hanako@flower', tel: '888-888' },
                   Sachiko: { mail: 'sachiko@happy', tel: '777-777' },
                   Jiro: { mail: 'jiro@change', tel: '666-666' },
               }
           }
       }
   }
   let app = Vue.createApp(appdata);
   app.mount('#app');
</script>

<tr v-for="(item,key) in items">のitemで、itemsオブジェクトの値{mail:xxxxとか}が、keyがキーの値(Taroとか)を取得できる。

この項目の最後にforとifを組み合わせたコードが紹介される。こちらは省略。


■まとめ

今回は、結構色々とボリューミーでしたw

優先順位がまとめられています。

まず、{{}}は覚えなきゃまずいらしい。この記述を使って、文字を出力するのが基本。

v-bindも大事らしい、v-bind:style="styles"が、style属性に切り替わり、stylesが、文字列stylesではなく、javascriptで書かれた内容が展開されるのが大事。

ifやforは、基本的な使い方がわかればOKらしい。

またtemplateの書き方は、vue3で多用される書き方ではなく、コンポーネントを使った内容が重要らしい。


vue.js楽しいが、まだまだいまいちどう使うのか、見えてこない事が多いですね。ですが、setIntervalを使って、真偽値を切り替えているだけなのに、表示が切り替わるのは面白いですね。これがユーザーの動作に対応する様にすると、調べるとよく出てくる言葉の、「リアクティブ」って事になるのかな?

今回は、大分長い記事になりました。次回からは、場合によってはchapter毎に一記事ではなく、もう少し短い内容で記事にするかもです。

この記事が気に入ったらサポートをしてみませんか?