我有一个待办事项列表,您可以添加新的待办事项,并通过单击复选框将每个待办事项标记为已完成,然后在页脚上按全部或活动或已完成的方式选择列表的项目可见性。
当我在页脚上选择“已完成”时,它仅显示已完成的项目。
问题是当我在完成视图中取消标记完成的项目时,剩余(尤其是下一个)项目的复选框显示不正确。
var STORAGE_KEY = 'todo mvc by vue';
var todoStorage = {
data: [],
fetch: function () {
return this.data;
},
save: function (data) {
this.data = data;
//localStorage.setItem(STORAGE_KEY, JSON.stringify(data));
}
}
var filters = {
all: function (todos) {
return todos;
},
active: function (todos) {
return todos.filter(todo => !todo.completed);
},
completed: function (todos) {
return todos.filter(todo => todo.completed);
}
}
var app = new Vue({
el: '.app',
data: {
todos: todoStorage.fetch(),
newTodo: '',
visiblitys: [{
title: 'All',
selected: true,
filter: filters.all
}, {
title: 'Active',
selected: false,
filter: filters.active
}, {
title: 'Completed',
selected: false,
filter: filters.completed
}]
},
computed: {
todosForShow: function () {
return this.currentFilter(this.todos);
},
currentFilter: function () {
return this.visiblitys.find(v => v.selected).filter;
}
},
watch: {
todos: {
handler: function (todos) {
todoStorage.save(todos);
},
deep: true
}
},
methods: {
deleteItem: function (todo) {
this.todos.splice(this.todos.indexOf(todo), 1);
},
deleteCompletedItem: function () {
this.todos = filters.active(this.todos);
},
addItem: function (todo) {
var value = this.newTodo && this.newTodo.trim();
if (!value) return;
this.todos.push({
content: value,
completed: false
});
this.newTodo = '';
},
selectVisiblity: function (visiblity) {
this.visiblitys.forEach(vis => vis.selected = false);
visiblity.selected = true;
},
completeAll: function () {
this.todos.forEach(todo => todo.completed = true);
}
}
});
* {
box-sizing: border-box;
}
header h1 {
text-align: center;
}
.container {
max-width: 800px;
margin: 0 auto;
}
.new-todo {
padding: 16px;
box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03);
font-size: 24px;
width: 100%;
}
li.completed {
text-decoration: line-through;
}
footer {
border-top: 1px solid #e6e6e6;
height: 20px;
padding: 10px 15px;
color: #777;
text-align: center;
position: relative;
}
.filters {
list-style: none;
margin: 0;
padding: 0;
position: absolute;
left: 0;
right: 0;
}
.filters li {
display: inline;
}
.filters li a {
margin: 3px;
padding: 3px 7px;
text-decoration: none;
border: 1px solid transparent;
border-radius: 3px;
color: inherit;
}
.filters li a.selected {
border-color: rgba(175, 47, 47, 0.2);
}
.todo-count {
float: left;
text-align: left;
}
.complete-all {
float: right;
cursor: pointer;
position: relative;
color: black;
}
.todo-list {
clear: both;
}
.clear-completed {
float: right;
cursor: pointer;
position: relative;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
font-weight: inherit;
color: inherit;
-webkit-font-smoothing: antialiased;
}
<header>
<h1>Todos</h1>
</header>
<div class="app container">
<input class="new-todo" type="text" v-on:keyup.enter="addItem()" v-model="newTodo"
placeholder="What needs to be done?">
<section class="main" v-show="todos.length > 0">
<button class="complete-all" @click="completeAll()">Complete All</button>
<ul class="todo-list">
<li v-for="todo in todosForShow" :class="{completed: todo.completed}">
<input type="checkbox" v-model="todo.completed">
{{todo.content}} -
<a href="#" @click.prevent="deleteItem(todo)">remove</a>
</li>
</ul>
<footer>
<span class="todo-count">{{todos.filter(t=>!t.completed).length}} items left</span>
<ul class="filters">
<li v-for="visiblity in visiblitys">
<a href="#" :class="{selected: visiblity.selected}"
@click.prevent="selectVisiblity(visiblity)">{{visiblity.title}}</a>
</li>
</ul>
<button class="clear-completed" v-show="todos.some(t=>t.completed)" @click="deleteCompletedItem()">Clear
Completed</button>
</footer>
</section>
<br>todos raw data:{{this.todos}}
</div>
<script src="https://cdn.jsdelivr.net/npm/vue"></script>