チームにVueを説明してみた。

この記事は[ウェブクルーAdvent Calendar 2020](https://qiita.com/advent-calendar/2020/webcrew) 17日目の記事です。
昨日は @maiunderwood さんの「 [スマホのCLS対策でやったこと](https://qiita.com/maiunderwood/items/cbe9fac4fd90e459e223) 」でした。

##はじめに
今回、私がチームの方々（受講者）に対してVueについて説明しました。
その際にどのような知識をどのような順で教えていったのかを紹介していきたいと思います。
この記事を見ていただいて、下記のようになれば幸いです。

- 受講者にとっては復習の資料
- Vueの初心者の方にとって、どのように学んでいくのが良いのかの参考資料
- これからチームにVueを導入するにあたっての参考資料


##説明するにあたって
下記が今回のVueの勉強会を開き、受講者に説明していくにあたっての前提条件になります。

| 説明者のレベル感   |  参考書を読んで、適当なものを作ったぐらいのレベル感                                                                                                 | 
| ---------------- | ------------------------------------------------------------------------------------------------- | 
| **受講者のレベル感** | **Vueを触ったことがない人がほとんど**                                                                 | 
| **目的**             | **受講者の方々がVueの基本的な部分を理解でき、Vueのコードを見た際にどのような処理をしているのか想定できるようになる** | 
| **最終的なゴール**  | **APIに保存しているデータを使い、VueでToDoリストが作成できるようになる**                                                  | 

##説明したことざっくり

下記のような順番で受講者の方々に説明していきました。合算すると勉強会は、12hでした。
個人的に「失敗したな〜」と思う勉強会が2h（1回分あるので）大体10hぐらいかかるかなと思われます。
次の章では、教えた内容、失敗したなと思う理由を併せて紹介していきたいと思います。

| 回数 | 内容 | 時間 | 
| ---- | ---- | ---- | 
| 1    |  <ul><li>なぜVueなのか?</li><li>ECMAScriptについて</li></ul>   | 1h   | 
| 2    |  <ul><li>Vueのオプション</li><li>v-〇〇系について</li></ul>     | 2h   | 
| 3    |  <ul><li>Vue-CLIについて</li></ul>     | 1h   | 
| 4    |  <ul><li>Vueの記述を使ったハンズオン（失敗）</li></ul>    | 2h   | 
| 5    |  <ul><li>Vueの記述を使ったハンズオン（成功）</li></ul>    | 2h   | 
| 6    |  <ul><li>ToDoリスト作成のハンズオン</li></ul>    | 2h   | 
| 7    |  <ul><li>ToDoリスト作成のハンズオン（API連携あり）</li></ul>     | 2h   | 

##教えた内容
###1回目
####なぜVueなのか?
ここで、JavaScriptのフレームワークが数ある中でなぜ、Angular、Reactではなく、Vueなのかについて「ドキュメントの読みやすさ」や「データバインディングの方向」、「学習コスト」の観点から理由を説明していきました。

####ECMAScriptについて
ここで、ECMAScript基、JavaScriptの基礎的な構文について説明していきました。
というのもVueの参考書や参考サイトでECMAScriptの書き方を用いて、説明するケースがあるためです。
私がここで説明したのは下記です。

 - let、const
 - アロー関数
 - this 

###2回目
####Vueのオプション
ここでは、タイトルの通りVueのオプションについて説明しました。
数ある中でよく使うであろう下記オプションについて説明しました。

 - data (管理するデータを定義する)
 - methods　(関数を定義する場所)
 - computed　(関数を定義する場所)

そして、上記の methods と computed の違い（**キャッシュを用いるか用いないか**）についてもDEMOを使い簡単に説明しました。

####v-〇〇系について
ここでは、Vueの記法である、v-〇〇系について説明していきました。
ここは、Vueの公式ドキュメント用いてよく使うであろう下記記法を簡単に説明しました。

| 記法    | 説明                                                                       | 
| ------- | -------------------------------------------------------------------------- | 
| v-model | 双方向のバインディングを行うことができる                                   | 
| v-on    | HTML側のイベントを検知するもの<br>v-onで検知することが可能なイベントの種類については下記記事参照 | 
| v-bind  | Vue側で管理しているデータをHTML側に反映させるもの                          | 
| v-show  | 表示・非表示を制御するもの（要素をdisplay:noneで消す）                     | 
| v-if    | 表示・非表示を制御するもの（要素自体を消す）                               | 
| v-for   | for文（繰り返し制御）                                                      | 

**受講用の資料を作る際に参考にさせていただいた記事**

 - [【Vue.js】イベントハンドリングをサンプルを作りながら理解する](https://qiita.com/b1san/items/6bc0be17cd6ed687520c)

###3回目
####Vue-CLIについて
ここでは、受講者各自のローカル環境に「Vue-CLI」をインストールしていただき、練習用のプロジェクト(設定はデフォルト)を作成していただいて、その構造について説明していきました。
最終ゴールであるToDoリストもVue-CLIで作ってもらうと思っていたので、慣れてもらう為にも構造の説明を行いました。

下記資料が構造を説明するにあたって、個人的に一番わかりやすいなと感じました。

**受講用の資料を作る際に参考にさせていただいた記事**

 - [これでわかるはじめてのvue-cli](https://reffect.co.jp/vue/finally-understand-vue-cli)
 - [Vue.js「コンポーネント」入門](https://qiita.com/kiyokiyo_kzsby/items/980c1dc45e00d2d3cbb4)

###4回目
#####Vueの記述を使ったハンズオン（失敗）
ここでは今までが、ほぼほぼ説明だったので、受講者の方々に手を動かしていただこうと思い、問題のテンプレートを8問作成し、それを共有してハンズオン形式でそれぞれの問題を解いていただきました。

一部抜粋するとこんな感じです。
それぞれの問題に対して、使うVueの記法(例：v-bindとv-forを使います的な)やヒントを記載しており、受講者の方々に解いていただきました。

> 変数count（初期値 0）をカウントアップしていってcountが偶数の場合に div leadの部分を非表示にしてください。
***
>ボタンを押すたびに #textのdiv要素が赤色と青色に切り替わるようにしてください。

**何が失敗だったのか？**
結構の受講者が詰まってしまい、時間内に解いた問題は4問ぐらいになってしまいました。
個人的には、以下が原因だったのかなと思っています。

  - **8個の問題がそれぞれ繋がっていない**
  - **問題やヒントに日本語が多すぎて理解するのに時間がかかる**
  - **復習の時間をあまりとらずに問題に入ってしまった**
  - **実際に触ることが初めてなのをもっと考慮するべきだった**

**8個の問題がそれぞれ繋がっていない**
ここに関しては、それぞれの問題に繋がりがないので受講者の方々は次の問題になるたびに頭をリセットしなければいけないので負担になってしまっていた。

**問題やヒントに日本語が多すぎて理解するのに時間がかかる**
ここも上記と同じで日本語をダラダラと書きすぎてしまったことによって、それを理解するのにむしろ負担になってしまいました。

**復習の時間をあまりとらずに問題に入ってしまった**
前々回にVueの記法について触れていたのですが、それから時間が経ってしまっていました。それによってVueの記法を忘れてしまっている方が多かったです。

**実際に触ることが初めてなのをもっと考慮するべきだった**
Vueを触ることが初めてなので、それをもっと考慮してヒントを出すべきでした。ヒントが薄すぎて、詰まってしまう受講者が多かったです。

###5回目
#####Vueの記述を使ったハンズオン（成功）
ここでは、再度ハンズオンの時間を設けました。
前回での反省を生かして振り返りやヒント(コード)の内容を濃くし、10個（最終問題は発展問題）問題を用意しました。
問題構成は下記です。
最終的には、問題9問を解けばローカルでのToDoリストが作成できているというものにし、1問1問を機能追加していくような感じにし、問題ごとの繋がりを意識しました。

※下記の問題では、v-forで表示させるリストデータは、事前でこちら側で用意しています。

| 問題番号 | ハンズオンの内容                                                                                                                         | 
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------- | 
| 1問目    | v-forを使った、リストデータの表示                                                                                                              | 
| 2問目    | 上記のリストで、ある項目のみv-bindで太字にする                                                                                             | 
| 3問目    | 上記の太字にするのをある条件時のみ適用<br>（ヒントに三項演算子について記載）                                                             | 
| 4問目    | 上記のリストで最後尾のリストを削除できるボタンを追加<br>（ヒントにpopメソッドについてを記載）                                            | 
| 5問目    | 上記のリストでそのリストが何番目かを先頭に表示させるものを作成<br>（ヒントにindex変数についてを記載）                                  | 
| 6問目    | 最後尾のリストを削除できるボタンからリスト内に削除ボタンを設置して、削除ボタンを押した際にそのリストを削除するものに変更<br>（ヒントにspliceメソッドについてを記載） | 
| 7問目    | 上記のリストで最後尾にベタ書きでデータ追加                                                                                               | 
| 8問目    | 上記の追加したデータをinput要素から値を変更できるようにする                                                                              | 
| 9問目    | 上記をinput要素で入力したものをリストデータに追加しv-forで表示できるようにする<br>（ヒントにpushメソッドについてを記載）           | 

今回は、問題数自体は多くはなりましたが、それぞれの問題が繋がっていたため、時間もあまりかからず、かつ
詰まってしまう受講者もいなかったです。

###6回目
#####ToDoリスト作成のハンズオン
ここでも、ハンズオン形式で進め、ToDoリストを作成していただきました。
前回と違う点としては、以下です。

 - コンポーネントを分けてもらう
 - localStrorageを使いリストデータをブラウザに保存する

問題としては、以下です。

| 問題番号 | ハンズオンの内容                                                                                                                         | 
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------- | 
| 1問目    | 前回作成したToDoリストを再度作成してもらう                                                                                                              | 
| 2問目    | 上記をコンポーネントに分けてもらう<br>（propsとemitについて説明）                                                                                       | 
| 3問目    | 上記でリストデータをlocalStorageに保存できる機能を実装 <br>（localStorageについて説明)                                                           | 

上記問題を詳しく話すと、以下です。
1問目では前回作成していただいたToDoリストを再度一から作ってもらいました。
2問目では、下記のようなにコンポーネントを分け、**子コンポーネントで親からもらったデータを変更してはいけない**ことを伝え、親と子でデータの受け渡しのためにpropsとemitを説明しました。

|      | 親（コンポーネントを使う側） | 子（コンポーネント） | 
| ---- | -------------------------- | -------------------- | 
| 役割 | コンポーネントを使う       | リストを表示         | 

|        | props                                                                                                                                                                                                                                 | emit                                                                                                                                                                                                | 
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | 
| 役割   | 子でデータを受け取る                                                                                                                                                                                                                  | 子でイベントが発生した際に検知して、親に伝えるかつ、引数を引き継ぐ                                                                                                                                  | 
| 使い方 | v-bindによって子でどのような名前でデータを使うかを定義でき、下記のように定義できる<br><br>props: {<br>&nbsp;&nbsp;&nbsp;&nbsp; lists: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; type: Array,<br>&nbsp;&nbsp;&nbsp; }<br>} | 親では<br>v-on:子で登録しているイベント = 親で登録しているイベント <br><br>子では<br>v-on:click="$emit('子で登録しているイベント',引数)"<br>これは、<br>v-on:click="親で登録しているイベント(引数)" | 

3問目では、localStorageを使ってリストデータをブラウザに保存し、リロードしても追加したデータなどが消えないようにしました。ここでは、localStorageの「値のセット」、「値の取り出し」、「値を削除する」を説明しました。それに加えライフサイクルでよく使うであろう「created」と「mounted」を説明しました。（良きタイミングでlocalStorageからリストデータを取り出すため）

###7回目
#####ToDoリスト作成のハンズオン（API連携あり）
ここでは、上記で作成したToDoリストのデータをAPI側で管理し、データを取り出したり、削除することを行いました。
今回使用したAPIは「Strapi API」です。
事前に受講者にはこのAPIを自身のローカル環境にインストールしていただき、リストデータをテーブルに登録していただきました。
StarpiのAPIに対しては、前回と同じで下記を行いました。

 - 値の取得  (GETメソッド)
 - 値の削除  (DELETEメソッド)
 - 値の追加  (POSTメソッド)

それをするにあたって、非同期通信について説明し、Vueでの非同期通信のaxois(アクシオス)をそれぞれのローカルにインストールし使用しました。

**受講用の資料を作る際に参考にさせていただいた記事**
 - [Headless CMS 軽く触って比較してみた(Contentful / microCMS / strapi / GraphCMS)](https://qiita.com/cheez921/items/81cba28e4b815709f863#strapi)
 - [Strapi (Headless CMS)を使ってみたので使い方まとめ + GraphQL](https://qiita.com/mtoyopet/items/46d3f6edbaaed4f0065c)
 - [axiosのget,post,deleteメソッド](https://qiita.com/chenglin/items/f59a6daff76fa0f582af)

##最後に
いかがだったでしょうか？
参考になる部分ならない部分等はあると思いますが、個人的に上記のVueの勉強会を開いてみて、なんだかんだ人に教えるということで、あやふやな知識を理解し直すことができ、自分の理解をより深めることができた良い復習の機会だったのかなと感じました。