LoginSignup
6
3

More than 3 years have passed since last update.

写経で感覚を掴むVue

Last updated at Posted at 2019-06-01

なんて事のない、TodoリストをVueで作ってみましょう。
Jun-01-2019 11-52-26.gif

注意点

理論の説明は省きます。

今回の目的は写経を通じて「なんとなくわかる」状態になっていただく事です。

Vueのチュートリアルを読んで挫折してしまった方は、こちらのコードを写経していただくと、肌感覚がつかめるかと思います。

ファイル構成

どこかしらにフォルダを作って、下記の構成でファイルを作成してみてください。
非常に単純です。

.
├── index.html
└── index.js

STEP1 TODOを表示する

htmlファイルの雛形を作る

とりあえずおきまりの雛形でも書いてみましょう.

index.html
<html>
  <head>
    <meta charset="utf-8">
    <title>Vue.js App</title>
  </head>
  <body>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="index.js"></script>
  </body>
</html>

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>はVueを使えるようにするためです。
本来であれば、npmやyarn等のパッケージ管理ツールを使ってインストールして、あれこれやる必要があるのですが、Vueは初心者に優しい。。。
この一行でVueが使えるようになります。

Vueインスタンスを定義する

TODOを表示するためのインスタンスを定義しましょう。

index.js
var app = new Vue({
  el: '#app',
  data: {
    todos: [
      {name: "todo1", state: true},
      {name: "todo2", state: true},
      {name: "todo3", state: false},
    ],
  }
})

el:の部分でVueインスタンスを反映させる要素を指定します。
今回は#app、つまり<div id="app"></div>で囲まれた部分に対して、Vueインスタンスを反映させます。

data:の部分は変数名、およびその初期値を定義します。
今回はtodos変数に3つの辞書を配列として定義しています。

Vueインスタンスを描画する

先ほど定義したVueインスタンスを用いて、htmlファイルの方で描画してみましょう。
index.htmlbodyタグに下記のように編集します。

index.html
<body>
  <div id="app">
    <div v-for="(item, index) in todos" v-bind:key="index">
      <input type="checkbox" v-bind:value="index" :checked="item.state"/>{{ item.name }}
      <br>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="index.js"></script>
</body>

ブラウザでindex.htmlを開いてみると、このようになるはずです。
スクリーンショット 2019-06-01 12.56.46(2).png

少し解説をいたします。

Vueには「ディレクティブ」という特別なトークンを定義することができます。
htmlファイル中のv-for...v-bind...と書かれた部分がそれに当たります。

これによって、繰り返し表示を行えたり、条件分岐によって表示を制御することができるのです。

詳しくはこちらのドキュメントを参照してみてください。

STEP2 TODOリストの各機能を実装

チェックボックスの状態をVueにも伝える

現状でも問題なくチェックボックスは利用できますが、Vue側でもその状態を反映させましょう。

methodを追加します。

index.js
var app = new Vue({
  el: '#app',
  data: {
    todos: [
      {name: "todo1", state: true},
      {name: "todo2", state: true},
      {name: "todo3", state: false},
    ],
  },
  methods: {
    changeState: function(index) {
      this.todos[index].state = !this.todos[index].state;
    }
  }
})

methodに記述するのは、そのVueインスタンスが利用できる関数です。
changeStateにより、クリックされたtodoのstate変数が変更されます。

changeStateを利用するために、index.htmlのファイルのcheckboxの行を下記のように修正しましょう。

<input type="checkbox" v-bind:value="index" :checked="item.state" v-on:click="changeState(index)"/>{{ item.name }}

これにより、checkboxがクリックされると、それに対応するtodoのstateが変更されます。

削除機能を追加

index.jsのmethodの部分を下記のように変更しましょう。

index.js
methods: {
  changeState: function(index) {
    this.todos[index].state = !this.todos[index].state;
  }
  deleteTodo: function(index) {
    this.todos.splice(index, 1);
  }
}

index.htmlに削除ボタンを追加します。

index.html
<body>
  <div id="app">
    <div v-for="(item, index) in todos" v-bind:key="index">
      <input type="checkbox" v-bind:value="index" :checked="item.state" v-on:click="changeState(index)"/>{{ item.name }}
      <button v-on:click="deleteTodo(index)">削除する</button>
      <br>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="index.js"></script>
</body>

追加機能を追加

削除機能を追加したと同様に、index.htmlindex.jsを編集しましょう。

最後の追加となるので、ソースコード全てを載せておきます。

index.js
var app = new Vue({
  el: '#app',
  data: {
    todos: [
      {name: "todo1", state: true},
      {name: "todo2", state: true},
      {name: "todo3", state: false},
    ],
    message: '',
  },
  methods: {
    changeState: function(index) {
      this.todos[index].state = !this.todos[index].state;
    },
    addTodo: function() {
      this.todos.push({name: this.message, state: false});
      this.message = '';
    },
    deleteTodo: function(index) {
      this.todos.splice(index, 1);
    }
  }
})
index.html
<html>
  <head>
    <meta charset="utf-8">
    <title>Vue.js App</title>
  </head>
  <body>
    <div id="app">
      <form @submit.prevent="addTodo">
        <input v-model="message" type="text">
        <button type='submit'>追加</button>
      </form>
      <div v-for="(item, index) in todos" v-bind:key="index">
          <input type="checkbox" v-bind:value="index" :checked="item.state" v-on:click="changeState(index)"/>{{ item.name }}
          <button v-on:click="deleteTodo(index)">削除する</button>
        <br>
      </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="index.js"></script>
  </body>
</html>

ここまでくると、記事の最初のgifのようになっているはずです。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3