<div id="app" class="container my-3">
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" id="basic-addon1">待辦事項</span>
</div>
<input type="text" class="form-control" placeholder="準備要做的任務" v-model="newTodo" placeholder="準備要做的任務" @keyup.enter="addTodo">
<div class="input-group-append">
<button class="btn btn-primary" type="button" @click="addTodo">新增</button>
</div>
</div>
<div class="card text-center">
<div class="card-header">
<ul class="nav nav-tabs card-header-tabs">
<li class="nav-item">
<a class="nav-link" href="#" :class="{'active': visibility == 'all'}" @click.prevent=" visibility ='all' ">全部</a>
</li>
<li class="nav-item">
<a class="nav-link " href="#" :class="{'active': visibility == 'doing'}" @click.prevent=" visibility ='doing' ">進行中</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#" :class="{'active': visibility == 'done'}" @click.prevent=" visibility ='done' ">已完成</a>
</li>
</ul>
</div>
<ul class="list-group list-group-flush text-left">
<li class="list-group-item" v-for="(item, key) in filteredTodos" @dblclick="editTodo(item)">
<div class="d-flex" v-if="item.id !== cacheTodo.id">
<div class="form-check">
<input type="checkbox" class="form-check-input" :id="item.id" v-model="item.completed">
<label class="form-check-label" :for="item.id" :class="{'completed': item.completed}">
{{ item.title }}
</label>
</div>
<button type="button" class="close ml-auto" aria-label="Close" @click="removeTodo(item)">
<span aria-hidden="true">×</span>
</button>
</div>
<input type="text" class="form-control" v-if="item.id == cacheTodo.id" v-model="cacheTitle" @keyup.esc="cancelEdit()" @keyup.enter="doneEdit(item)">
</li>
</ul>
<div class="card-footer d-flex justify-content-between">
<span>還有 {{ uncompletedCount }} 筆任務未完成</span>
<a href="#" @click.prevent="cleanAll">清除所有任務</a>
</div>
</div>
</div>
var app = new Vue({
el: "#app",
data: {
newTodo: "",
todos: [
],
cacheTodo: {},
cacheTitle: "",
visibility: "all",
uncompletedTodos: [],
uncompletedNum: ""
},
methods: {
addTodo: function() {
var value = this.newTodo.trim();
if (!value) {
return;
}
var timestamp = Math.floor(Date.now());
this.todos.push({ id: timestamp, title: value, completed: false });
this.newTodo = "";
},
removeTodo: function(todo) {
var vm = this;
var newIndex = vm.todos.findIndex(function(item, key) {
return todo.id === item.id;
});
this.todos.splice(newIndex, 1);
},
editTodo: function(item) {
this.cacheTodo = item;
this.cacheTitle = item.title;
},
cancelEdit: function() {
this.cacheTodo = {};
},
doneEdit: function(item) {
item.title = this.cacheTitle;
this.cacheTitle = "";
this.cacheTodo = {};
},
cleanAll: function() {
this.todos = [];
}
},
computed: {
filteredTodos: function() {
if (this.visibility == "all") {
return this.todos;
} else if (this.visibility == "doing") {
var anotherTodos = [];
this.todos.forEach(function(item) {
if (!item.completed) {
anotherTodos.push(item);
}
});
return anotherTodos;
} else if (this.visibility == "done") {
var anotherTodos = [];
this.todos.forEach(function(item) {
if (item.completed) {
anotherTodos.push(item);
}
});
return anotherTodos;
}
},
uncompletedCount: function() {
var uncompletedTodos = this.todos.filter(function(item) {
return item.completed == false;
});
return uncompletedTodos.length;
}
}
});