【こいつ…動くぞ!】おじさんと一緒にToDoアプリチュートリアル(3)【Vue.js】


ご覧いただきありがとうございます!UGと申します!

前回の「 おじさんと一緒にToDoアプリチュートリアル(2)」の続きです。

前回やっと「動くぞ!」を体感していただけたかと思います。

今回は、「まだ動く!?」を体験していただければと思います!!!


前回は動的に文字を動かしました。

今回は、実際にtodoリストを追加して!さらなる「動くぞ!!」を体感していただきたいです。

※ html・css・JavaScriptが何となく書ける方向けです
※今回、vue-cliは使用しません。基本的なVueの機能を体感したい、という人向けです。

1.本記事でのゴール!と実装する上での考え方

最終的なゴール

最終的なゴールは上記gif画像の通りです。前回と同様です。

1.Vueを使って文字を表示する
2.inputタグに入力した文字をブラウザ上に反映させる
3.todoリストを表示させる
4.todoリストに表示させる部品を作成する
5.inputタグに入力した文字をtodoリストへ反映させる
6.削除ボタンを押す事でtodoリストからアイテムを削除させる

これらの動作を実装していきたいと思います!

本記事でのゴール!

本記事でのゴールは上記3

「 todoリストを表示させる 」

※前回用意したinputタグに入力し、その値がtodoリストとして表示される、と捕らえてください。

を目標にしていきたいと思います!

実装する上での考え方


1.data型にオブジェクトとしてtodoリストを用意、配列として格納。

2.ul・liタグを用意して、todoリストをhtmlとして表示させる

3.前回記事で実装したmodelから、todoリスト配列へ入れ込む

4.入力する上でのバリデーションを設ける

2.今回のファイル構成

test
│  index.html
│
└─js
    index.js


前回と同様のファイル構成です。

説明は割愛させていただきます。

ファイルの中身を見たい、という方は、前回の記事を参照してください。

3.v-forを用いて、todoリストを表示させる!

index.jsにToDoリストの配列を用意

new Vue({
  el: "#app",
  data: () => ({
    message: "sample",
    list: [
      { id: 1, text: "todoリスト1" },
      { id: 2, text: "todoリスト2" },
    ],
  }),
});

前回記事最終コードに「list」というデータ型を追加しました!(5・6・7行目)

「何番目のリストか」を表す「 id 」、「 todoの内容 」としての「 text 」 を配列としてlistへ格納しました。

あとはこれを、htmlとして出力します。

出力する際は、foreachのような役割を果たす、「v-for」を用います。

index.htmlにul/liタグを用意し、liタグにv-forを記載する

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>hello!!!</h1>

    <div id="app">
      <div id="message">
        <input type="text" v-model="message" />
        <p>{{ message }}</p>
      </div>
      <!-- ul liタグを用意する -->
      <div class="todo">
        <ul class="todo-content">
          <li
            class="todo-content-item"
            v-for="item in list"
            v-bind:key="item.id"
          >
            {{ item.id }}:{{ item.text }}
          </li>
        </ul>
      </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="./js/index.js"></script>
  </body>
</html>


前回最終コードに、先ほど準備した配列を吐き出す為のul liタグを加えました!(17~27行目)

~解説~

・v-for

foreachのようなモノです。JSのforの記載方法と同じように記載します。

listという配列をitemとして返す!といった具合です。
itemとして返されているものには、indexjsで記載したidとtextの情報が含まれています。

これを{{ item.id }}、{{ item.text }}としてhtmlとして表示させます

※{{ }}この記載ってなんぞ?という方は、前々回の記事をご覧ください

・v-bind:key

Vueが v-forをする際に 「配列の中の何番目を表示しているのか把握する」為の目印の役割となります。

v-bind:keyを与えなくても表示されますが、公式マニュアルでも推奨しており、 v-bind:key を与えないことで、「 表示は消えるけど要素は残る 」等、思わぬ挙動をするときもあります。

マニュアルに則り、v-bind:keyを表示するようにしましょう

4.ボタンを配置、v-onでtodoリストに加える

index.htmlにボタンを用意して、 v-on:click=”addTodoList” を加えてあげる

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>hello!!!</h1>

    <div id="app">
      <div id="message">
        <input type="text" v-model="message" />
        <button
          v-on:click="addTodoList"
        >
          todoリストに加える
        </button>
        <p>{{ message }}</p>
        
      </div>
      <!-- ul liタグを用意する -->
      <div class="todo">
        <ul class="todo-content">
          <li
            class="todo-content-item"
            v-for="item in list"
            v-bind:key="item.id"
          >
            {{ item.id }}:{{ item.text }}
          </li>
        </ul>
      </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="./js/index.js"></script>
  </body>
</html>

考え方工程3.前回記事で実装したmodelから、todoリスト配列へ入れ込む

に入っていきます。htmlにボタンを用意して、

v-on:click=”addTodoList”

を配置してあげます
※v-onってなんぞ?の方は前回の記事を見てみてください!

index.jsで addTodoList を定義してあげる

new Vue({
  el: "#app",
  data: () => ({
    message: "sample",
    list: [
      { id: 1, text: "todoリスト1" },
      { id: 2, text: "todoリスト2" },
    ],
  }),
  methods: {
    addTodoList() {
      // 現在の配列の個数から、次のid番号を取得する
      const nextId = this.list.length + 1;

      // v-modelで入力されたmessageを新たなtodotextとする
      const todoText = this.message;

      // listと同様のオブジェクトにする
      const newTodo = {id:nextId, text: todoText};

      // 配列に加える
      this.list.push(newTodo);

   // 配列に加えた後、inputの中身を空にする
      this.message = '';
    }
  },
});

10行目以降に、addTodoListメソッドを定義させました。
以下の流れとなります。

1.追加するIDを取得するために、配列の個数を数え(length) 、それに1を加えたモノを新たに追加するためのIDとして設置

2.todoリストの内容は、modelで設定している「message」とするため、this.messageとする

3.新たなIDとtextをlistと同じオブジェクトにして、

4.push()で配列の一番後ろに入れる!

5.push()した後は、inputタグの中に文字が残らないように、messageを空にする

という流れをmethodとして定義させました!

5.こいつ・・・動くぞ!

ここまでお付き合い頂いた方は、

動く!!

動くぞ!!!


となっているかと思います!!!

今のままでも基本的な動作は出来ていますが、空白のToDoリストでも入力可能な状態となっており、少しかっちょ悪いので、

「空文字だと入力出来ない」

というバリデーションを加えましょう!!!

6.computedを用意して、ボタンdisabledを操作

        <button
          v-on:click="addTodoList"
          v-bind:disabled="isDisabled"
        >
          todoリストに加える
        </button>

  methods: {
    addTodoList() {
      // 現在の配列の個数から、次のid番号を取得する
      const nextId = this.list.length + 1;
      // v-modelで入力されたmessageを新たなtodotextとする
      const todoText = this.message;
      // listと同様のオブジェクトにする
      const newTodo = {id:nextId, text: todoText};
      // 配列に加える
      this.list.push(newTodo);
      this.message = '';
    }
  },
  computed: {
    isDisabled() {
      if(this.message.length <= 0) {
        return true;
      } else {
        return false;
      }
    }
  },

index.jsとindex.htmlにて、バリデーションに関する部分だけ抜粋して、追加のコードを記載しております。


・ v-bind:disabled=”isDisabled”
disabledをv-bindしております。isDisabledをjs側で

「message」が「文字数0の時」と「文字数が1以上の時」

と条件を付けてあげて、true,falseを返してあげます。

・computed
算出プロパティと呼ばれるモノです。
既存のプロパティを算出した結果を取得するモノです
※ここでは、messageを算出して、結果を返す、という行為に当たります。

・if()以下
this.messageにてmessageを取得し、lengthにて文字数へ返還、0以下であればdisabledをtrue、それ以外であればfalseを返しています。

ここまで記載していただければ、文字数によってボタンが押せたり、押せなかったりの挙動が確認できるはずです!!

まとめ

本記事での最終的なコード

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>hello!!!</h1>

    <div id="app">
      <div id="message">
        <input type="text" v-model="message" />
        <button
          v-on:click="addTodoList"
          v-bind:disabled="isDisabled"
        >
          todoリストに加える
        </button>
        <p>{{ message }}</p>
      </div>
      <!-- ul liタグを用意する -->
      <div class="todo">
        <ul class="todo-content">
          <li
            class="todo-content-item"
            v-for="item in list"
            v-bind:key="item.id"
          >
            {{ item.id }}:{{ item.text }}
          </li>
        </ul>
      </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="./js/index.js"></script>
  </body>
</html>
new Vue({
  el: "#app",
  data: () => ({
    message: "sample",
    list: [
      { id: 1, text: "todoリスト1" },
      { id: 2, text: "todoリスト2" },
    ],
  }),
  methods: {
    addTodoList() {
      // 現在の配列の個数から、次のid番号を取得する
      const nextId = this.list.length + 1;
      // v-modelで入力されたmessageを新たなtodotextとする
      const todoText = this.message;
      // listと同様のオブジェクトにする
      const newTodo = {id:nextId, text: todoText};
      // 配列に加える
      this.list.push(newTodo);
      this.message = '';
    }
  },
  computed: {
    isDisabled() {
      if(this.message.length <= 0) {
        return true;
      } else {
        return false;
      }
    }
  },
});

いかがだったでしょうか

本記事にて

・v-forの使い方
・ computedの使い方

を紹介いたしました!

次回は、今回配列を表示させるために用いたul・liタグの部分を部品化して別ファイルに記載し、取り出していきたいと思います!

それでは、今回はここで失礼いたします!