#app.container.my-3
.input-group.mb-3
.input-group-prepend
span#basic-addon1.input-group-text 待辦事項
input.form-control(type='text' placeholder='準備要做的任務' v-model='newTodo' @keyup.enter='addTodo')
.input-group-append
button.btn.btn-primary(type='button' @click='addTodo') 新增
.card.text-center
.card-header
ul.nav.nav-tabs.card-header-tabs
template(v-for='(item, index) in visibilityList')
li.nav-item(:key='index')
a.nav-link(href='#' :class=" {'active' : visibility == item.value } " @click='visibility=item.value') {{item.name}}
ul.list-group.list-group-flush.text-left
template(v-for='(item) in filteredTodos')
li.list-group-item(:key='item.id' @dblclick='editTodo(item)')
.d-flex(v-if='item.id !== cacheTodo.id')
.form-check
input.form-check-input(:id='item.id' type='checkbox' @click='changeComplated(item.id)' v-model='item.completed')
label.form-check-label(:for='item.id' :class="{'completed':item.completed}") {{ item.title }}
button.close.ml-auto(type='button' aria-label='Close' @click='removeTodo(item)')
span(aria-hidden='true') ×
input.form-control(type='text' v-model='cacheTitle' v-if='item.id == cacheTodo.id' @keyup.esc='cancelEdit' @keyup.enter='doneEdit(item)')
.card-footer.d-flex.justify-content-between
| {{`還有${activeTodosLength}筆任務未完成`}}
a(href='#' @click='cleanTodo') 清除所有任務
View Compiled
var urlAPI = "https://eudora-hsj.github.io/Vue-practice/data/todolist.json"
var app = new Vue({
el: "#app",
data() {
return {
newTodo:'',
todos: [],
visibilityList: [
{ name: "全部", value: "all" },
{ name: "進行中", value: "active" },
{ name: "已完成", value: "completed" }
],
visibility: 'all',
cacheTodo: {},
cacheTitle: '',
}
},
created() {
this.getList(urlAPI)
},
methods: {
getList(url) {
axios
.get(url)
.then((res) => {
this.todos = res.data.data
})
.catch((err) => {
console.log(err)
})
},
addTodo() {
let newTodoStr = this.newTodo.trim()
if (!newTodoStr) {
return
}
this.newTodo = ""
let submitData = {
id: Math.floor(Date.now()),
title: newTodoStr,
completed: false
}
this.todos.push(submitData)
},
removeTodo(item) {
this.todos.splice(this.getIndex(item.id), 1)
},
editTodo(item) {
this.cacheTodo = item
this.cacheTitle = item.title
},
cancelEdit() {
this.cacheTodo = {}
},
doneEdit(item) {
item.title = this.cacheTitle
this.cacheTitle = ""
this.cacheTodo = {}
},
cleanTodo() {
this.todos.splice(0, this.todos.length)
},
getIndex(id) {
return this.todos.findIndex((el) => el.id == id)
},
changeComplated(id){
let index = this.getIndex(id)
this.todos[index].completed = !this.todos[index].completed
}
},
computed: {
filteredTodos() {
let nowTab = this.visibility
switch (nowTab) {
case "all":
return this.todos.filter((item) => true)
case "active":
return this.todos.filter((item) => !item.completed)
case "completed":
return this.todos.filter((item) => item.completed)
}
},
getNewKey() {
return Math.max(...this.todos.map((el) => +el.id))
},
activeTodosLength() {
return this.todos.filter((item) => !item.completed).length
}
}
})