[Vue.js]ドットインストールで作ったTodoアプリをv2.5.13に対応させる

vue.jsでTodoアプリを作る動画があるんですが、versionが古く(v0.11.4)、最新版にしたら動かなかったので書き直しました。

1/19日時点での最新版はv2.5.13です。
inputタグに一文字以上入力しないとTodoを追加できない機能を足しています。

下記は書き直したものです。
コピペすれば動きます。

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>My ToDos</title>
    <style>
body { font-size: 13px; font-family: Arial; }
h1 { font-size: 14px; border-bottom: 1px solid #ddd; padding: 0 0 5px; } 
ul { list-style-type: none; padding: 0; margin: 0 0 5px; }
ul > li { padding: 0 0 5px; }
input[type=text] { padding: 4px; border-radius: 4px; }
.done { text-decoration: line-through; color: #aaa; }
.linkLike { color: blue; cursor: pointer; }
    </style>
</head>
<body>
    <div id="myapp">
        <h1>
            My ToDos
            <small>{{remaining}}/{{todos.length}}</small>
            <span class="linkLike" v-on:click="purge">[purge]</span>
        </h1>
        <ul>
            <li v-for="(item, index) in todos">
                <input type="checkbox" v-bind:checked="item.done" v-on:click="item.done = !item.done">
                <span v-bind:class="{ done: item.done }">{{index + 1}}のタスク::{{item.task}}</span>
                <span class="linkLike" v-on:click="del(index)">[x]</span>
                <span class="linkLike" v-on:click="del(index)">{{item.times}}</span>
            </li>
        </ul>
        <input type="text" v-model="newTask" placeholder="new task...">
        <button v-on:click="add" v-bind:disabled="check">追加</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    <script>
        const vm = new Vue({
            el: '#myapp',
            data: {
                newTask: '',
                todos: [
                    
                ],
                checked : true
            },
            computed: {
                remaining: function(){
                    let count = 0;
                    let j = this.todos.length;
                    for (let i = 0; i < j; i++ ){
                        if(!this.todos[i].done){
                            count++;
                        }
                    }
                    return count;
                },
                check: function(){
                    if(this.newTask.length > 0) {
                        this.checked = false;
                    } else {
                        this.checked = true;
                    }
                    return this.checked;
                }
            },
            methods: {
                add: function() {
                    const jikan = new Date();
                    this.todos.push({
                        task: this.newTask,
                        done: false,
                        times: `${jikan.getHours()}-${jikan.getMinutes()}-${jikan.getSeconds()}`
                    });
                    this.newTask = ''
                },
                del: function(index) {
                    if (confirm("are you sure?")) {
                        this.todos.splice(index, 1)
                    }
                },
                purge: function(){
                    let i = this.todos.length;
                    while (i--) {
                        if (this.todos[i].done) {
                            this.todos.splice(i, 1)
                        }
                    }
                }
            }
        })
    </script>
</body>
</html>
```

## 修正箇所
修正した箇所を書いていきます。

### v-on

```html
<!-- v0.11.4 --> 
<span class="linkLike" v-on="click:purge">[purge]</span>

<!-- v2.5.13 --> 
<span class="linkLike" v-on:click="purge">[purge]</span>

<!-- v2.5.13(省略記法) --> 
<span class="linkLike" @click="purge">[purge]</span>
```

### v-repeat, v-attr, v-class
* v-repeatからv-forに修正
* v-attrからv-bindに修正
* v-classからv-bind:classに修正

```html
<!-- v0.11.4 --> 
<ul>
  <li v-repeat="todos">
    <input type="checkbox" v-attr="checked: done" v-on="click: done = !done">
    <span v-class="done: done">{{$index + 1}}のタスク::{{task}}</span>
    <span class="linkLike" v-on="click:del($index)">[x]</span>
    <span class="linkLike" v-on="click:del($index)">{{times}}</span>
  </li>
</ul>

<!-- v2.5.13 --> 
<ul>
  <li v-for="(item, index) in todos">
    <input type="checkbox" v-bind:checked="item.done" v-on:click="item.done = !item.done">
    <span v-bind:class="{ done: item.done }">{{index + 1}}のタスク::{{item.task}}</span>
    <span class="linkLike" v-on:click="del(index)">[x]</span>
    <span class="linkLike" v-on:click="del(index)">{{item.times}}</span>
  </li>
</ul>
```

v-for使用時に、indexがいらなければ下記の書き方で。

```html
<li v-for="item in todos">
```

## disabled
formを作る時に、disabledはよく使うのでメモ。

computedプロパティーを使用しています。
checkの戻り値がtrueの時はdisabledが有効になります。

```html
<div id="app">
  <input type="text" v-model="newTask" placeholder="new task...">
  <button v-bind:disabled="check">追加</button>
</div>

<script>

const vm = new Vue({
  el: '#app',
  data: {
    newTask: '',
    checked: true
  },
  computed: {
    check: function(){
      if(this.newTask.length > 0) {
        this.checked = false;
      } else {
        this.checked = true;
      }
        return this.checked;
    }
  }
})

</script>
```

## まとめ
最新版の方がとっつきやすかった気がします。
リファレンスも日本語で書かれているのでありがたいです。


## 参考URL
[Vue.js公式リファレンス](https://jp.vuejs.org/v2/guide/)
[ドットインストール](https://dotinstall.com/)