見出し画像

Vueでtodoリストを作成するチュートリアル

VuejsはCDNでカンタンに使える

知っておきたいのが、普通のJavaScriptと同じように、vuejsはCDNで使えること。

HTMLの静的サイトを模写するときに、JavaScriptやjQueryをHTMLの下の方にCDNのscriptタグを挿入して使ったりしますが、同じくvuejsも使えます。

予想以上にカンタンに使えることに僕も驚きでした。

具体的には、下記のようにCDNのscriptタグを挿入

<html>
  <body>
    <!-- development version, includes helpful console warnings -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </body>
<html>

これだけでvuejsが使えます。


vue.jsの公式ドキュメントが分かりやすく、始め方から学べます。

僕は公式ドキュメントでもvuejsの勉強を進めています。普通、公式ドキュメントは読みづらいことが多いけど、vuejsの公式ドキュメントはとても分かりやすいと思いました。


CDNとは

・Contents Delivery Networkの略

イメージ

vuejsを動作させるためのコードが外部のサーバーに保存されてあって、

そこから動作させるためのコードを自分のHTMLファイル内に読み込むことでvuejsが使えるイメージ。

他のメリットなどは、下記リンクのサイトが分かりやすかったと思います。


今回、PCのデスクトップにindex.htmlを作り、カンタンなtodo機能を作ってみましょう。

vue公式サイトに公開されているコードを基にして作りました。

完成イメージはこんな感じです。

スクリーンショット 2020-05-09 21.47.32

重要:

作る過程を大切にして説明していきたいと思います。

なぜかというと、

・シンプルな機能でも、vuejsではデータのやりとりなどあちこち行ったり来たりするので、シンプルな機能でも作り込むことが難しいと感じたこと。

・写経でお手本コードを見つつ、コードの最初の行から終わりの行まで順番に入力して単にコードを写すだけでは、過程など考えないので、身につきにくい。

今回僕がお手本コードを見て作ったtodoリストにしても、お手本はあるにしても、ゼロから作るのをイメージして作りました。

ゼロから作るならどうする?と想像してみると、まず完成の見た目をイメージします。


完成イメージを書き出す

まず見た目を考えてみます。

・todoを一覧表示する。

・todoを追加するためのフォームとtodo一覧を表示


機能(仕様)

・todo機能なので、todo項目の追加が必要

→フォームから入力してボタンを押すとtodoの一覧に追加され、表示されるようにする。

・追加されたtodoを削除したい

→todoの横に削除ボタンを設置し、ボタンを押したら削除され表示が消えるようにする。


とりあえず上記はHTMLでできそうなので、書いてみる

HTMLで可能な見た目やボタン、フォームを作る。

divとformとul,li要素をとりあえず書く感じでいいかと思います。


HTMLの他に、

・bootstrap・・・見た目を整えるのに使用

・vue.js・・・vue.jsを使うために使用

もCDNを入れておきます。

// todo.html

<!doctype html>
<html lang="ja">
 <head>
   <!-- Required meta tags -->
   <meta charset="utf-8">
   <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

   <!-- Bootstrap CSS -->
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

   <title>Todo App</title>
 </head>
 <body>
   <div>
     <form>
       <label for="new-todo">Add a todo</label>
       <input
         placeholder="noteを書く"
       >
       <button>Add</button>
     </form>
       <ul>
         <li>Something1 <button>削除</button></li>
         <li>Something2 <button>削除</button></li>
         <li>Something3 <button>削除</button></li>
       </ul>
   </div>
   <!-- development version, includes helpful console warnings -->
   <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
   <!-- Optional JavaScript -->
   <!-- jQuery first, then Popper.js, then Bootstrap JS -->
   <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
   <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
 </body>
</html>

上記のコードの見た目はこちら。

スクリーンショット 2020-05-20 19.09.29


inputに追加したいtodoを入力して、Addボタンを押して下のリストに追加されるようにする。

とりあえず、固定でtodoを表示させておきます。追加したtodoは現在表示されているリスト(Something3)の下に追加されるようにすればokですね。

todoの横に表示させる削除ボタンですが、liの外側に置くと改行されてしまうので、li要素の中に入れ込んでます。

見た目的には、これで完成でよさそう。


次は、vueで機能を作り込んでいきます。

vueを使うので、HTMLの要素を囲っている、いちばん上位の階層のdiv要素をインスタンス化することで、divの中身をvueの操作対象にできます。


まず、div要素のid名を適当に決めて、書きます。

<body>
  <div id="todo-list">
    <form>
    ...

<div id="todo-list">のように、idをtodo-listとします。

Vueインスタンスのelを上記id名にしたら、divおよびdivの中身がVueインスタンス化されます。

// vueのCDNの下にコードを挿入

・・・
</div>

<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

<!-- vue -->
<script type="text/javascript">
  new Vue({
       el: '#todo-list',
     })
</script>


これで、vueを使う準備が整ったので、まず、フォームからデータを入力してボタンを押したらli要素のtodoの一覧に追加され、表示されるようにしてみます。


formのinput要素でデータを入力→buttonを押す→メソッドを使って入力したデータをdataプロパティのオブジェクトに挿入

li要素にvueのv-forディレクティブを使い、dataプロパティのオブジェクトに挿入したデータをli要素で展開する。

上記の流れで作っていきます。


input要素に入力したデータをvueのdataプロパティに渡すことと、

上記の逆もできるように、input要素にv-modelディレクティブを使います。


vueのdataプロパティとinput要素のv-modelディレクティブに使う値をnewTodoTextという名前にします。

// v-model
<form>
    <label for="new-todo">Add a todo</label>
    <input
         id="new-todo"
         v-model="newTodoText"
         placeholder="noteを書く"
    >
    <button>Add</button>
</form>
// dataプロパティ
new Vue({
       el: '#todo-list',
       data: {
         newTodoText: '',
     }

これで、input要素とvueで双方向のデータのやりとりができる状態になりました。

次は、buttonを押すと、入力したデータを配列のdataプロパティのオブジェクトに挿入するメソッドを定義します。

newTodoTextでデータを受け取って、そこから別途準備したdataプロパティのオブジェクトに入れます。

v-forでは、複数のデータをひとつずつ取り出してli要素にデータを挿入するので、dataプロパティのオブジェクトを配列の形で保存できるようにするため、別途dataプロパティを準備する感じです。

この別途準備するプロパティを下記コードのように、todosとします。

new Vue({
       el: '#todo-list',
       data: {
         newTodoText: '',
         todos: [
           {
             title: '寝起きにvue'
           },
         ]
       },

todos.titleにnewTodoTextのデータを挿入します。

todosはデータベースみたいなイメージで、全部のtodoが、

{title: ほげほげ}

{title: fugafuga}

・・・

の形で保存される感じです。


todosに入ったtodoをv-forを定義したli要素でひとつずつ取り出し、表示します。

これをやってみましょう。

まずは、methodsを定義します。

form要素に、下記を追加します。

<form v-on:submit.prevent="addTodoText">

こうすることで、buttonを押したら、addTodoTextメソッドが実行されます。

.preventは、buttonを押したときに、ブラウザがリロードされないようにするために使います。

form要素の全体像は下記です。

<div id="todo-list">
    <form v-on:submit.prevent="addTodoText">
      <label for="new-todo">Add a todo</label>
      <input
         id="new-todo"
         v-model="newTodoText"
         placeholder="noteを書く"
      >
      <button>Add</button>
    </form>
・・・


addTodoTextメソッドを定義します。

new Vue({
       el: '#todo-list',
       data: {
         newTodoText: '',
         todos: [
           {
             title: '寝起きにvue'
           },
         ]
       },
       methods: {
         addTodoText: function () {
           this.todos.push({
             title: this.newTodoText
           })
           this.newTodoText = ''
         }
       }
     })

thisを使うことで、プロパティにアクセスできます。

thisのtodosのtitleに、newTodoTextのデータをpushすることで挿入します。

そして、挿入後にvue側からnewTodoTextのデータを空文字にすることで、inputに入力した文字が空文字でリセットされます。

これをしないと、ブラウザの文字入力欄に入力した文字が残ったままになってしまいます。

以上で、

ブラウザでinput要素にデータを入力

→vueでデータの保管庫がわりのtodosに入れる

までができましたので、todosのデータをli要素でv-forを使って展開していきましょう。


<ul>
   <li
     v-bind:key="todo.index"
     v-for="(todo, index) in todos"
    ></li>
</ul>

todosのデータをひとつずつ、todoに入れます。

todoと一緒にindexも渡しています。

indexは0から始まる連番です。

1個目のtodo→index = 0

2個目 のtodo→index = 1

・・・

のように連番となります。

v-forを使うとき、indexのようなkeyを明確にすることが推奨されています。

keyは、idやindexなど、数字じゃないといけないです。

v-bind:keyを書かずにコードを実行すると、warningが表示されます。

ここでは、v-bind:key="todo.index" をv-forでtodosをtodoに1個ずつ展開していくときの連番のよりどころにしています。

①v-forでtodosからtitleを取り出し、todoに保存する。

②index番号をtodoに保存する

③v-forで展開した要素の連番のよりどころは②だよ、とv-bind:key="todo.index"で明示する。


以降、また続きは編集します。

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