LoginSignup
8
4

More than 5 years have passed since last update.

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

Posted at

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

<!-- 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に修正
<!-- 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がいらなければ下記の書き方で。

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

disabled

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

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

<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公式リファレンス
ドットインストール

8
4
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
8
4