基本功能:
显示所有待办列表(点击不同的文本进行显示)
没完成的待办
已完成的待办
新建待办test
清除待办foo
代码js文件:
//index.js
//获取应用实例
const app = getApp();
Page({
data: {
todo: '',
todos: [
{
"id": 1474894720002,
"todo": "foo",
"completed": false
},
{
"id": 1474894720922,
"todo": "bar",
"completed": true
},
{
"id": 1474894723594,
"todo": "baz",
"completed": false
}
],
filterTodos: [],
filter: 'all',
activeCount: 0,
},
bindTodoInput(e) {
this.setData({
todo: e.detail.value
});
},
saveTodo(e) {
if (this.data.todo.trim().length === 0) {
return;
}
const newTodo = {
id: new Date().getTime(),
todo: this.data.todo,
completed: false,
};
this.setData({
todo: '',
todos: this.data.todos.concat(newTodo),
filterTodos: this.data.filterTodos.concat(newTodo),
activeCount: this.data.activeCount + 1,
});
},
todoFilter(filter, todos) {
return filter === 'all' ? todos
: todos.filter(x => x.completed === (filter !== 'active'));
},
toggleTodo(e) {
const { todoId } = e.currentTarget.dataset;
const { filter, activeCount } = this.data;
let { todos } = this.data;
let completed = false;
todos = todos.map(todo => {
if (Number(todoId) === todo.id) {
todo.completed = !todo.completed;
completed = todo.completed;
}
return todo;
});
const filterTodos = this.todoFilter(filter, todos);
this.setData({
todos,
filterTodos,
activeCount: completed ? activeCount - 1 : activeCount + 1,
});
},
useFilter(e) {
const { filter } = e.currentTarget.dataset;
const { todos } = this.data;
const filterTodos = this.todoFilter(filter, todos);
this.setData({
filter,
filterTodos,
});
},
clearCompleted() {
const { filter } = this.data;
let { todos } = this.data;
todos = todos.filter(x => !x.completed);
this.setData({
todos,
filterTodos: this.todoFilter(filter, todos),
});
},
todoDel(e) {
const { todoId } = e.currentTarget.dataset;
const { filter, activeCount } = this.data;
let { todos } = this.data;
const todo = todos.find(x => Number(todoId) === x.id);
todos = todos.filter(x => Number(todoId) !== x.id);
this.setData({
todos,
filterTodos: this.todoFilter(filter, todos),
activeCount: todo.completed ? activeCount : activeCount - 1,
});
},
onLoad() {
console.log('onLoad');
const that = this;
const activeCount = this.data.todos
.map(x => x.completed ? 0 : 1)
.reduce((a, b) => a + b, 0);
that.setData({
activeCount,
filterTodos: this.data.todos
});
}
});
wxml:
<scroll-view class="container" scroll-y="true">
<view class="todo">
<input class="new-todo"
placeholder="添加待办列表"
value="{{todo}}"
bindinput="bindTodoInput"
/>
<button type="primary" class="new-todo-save" bindtap="saveTodo">→</button>
</view>
<view class="todo-footer">
<text class="total">{{activeCount}} 个待办</text>
<view class="filter">
<text bindtap="useFilter"
data-filter="all"
class="{{ filter === 'all' ? 'filter-item filter-active' : 'filter-item'}}"
>所有</text>
<text bindtap="useFilter"
data-filter="active"
class="{{ filter === 'active' ? 'filter-item filter-active' : 'filter-item'}}" >待办</text>
<text bindtap="useFilter"
data-filter="completed"
class="{{ filter === 'completed' ? 'filter-item filter-active' : 'filter-item'}}"
>已完成</text>
</view>
<text wx:if="{{ todos.length - activeCount != 0 }}" class="clear" bindtap="clearCompleted">清除完成项</text>
<text wx:else class="clear-empty"></text>
</view>
<view class="todo-list">
<view class="todo-item" wx:for="{{filterTodos}}" wx:key="id">
<icon bindtap="toggleTodo" class="todo-check"
data-todo-id="{{item.id}}"
type="{{ item.completed ? 'success_circle' : 'circle'}}" />
<text class="{{ item.completed ? 'todo-content todo-completed' : 'todo-content'}}">{{item.todo}}</text>
<icon bindtap="todoDel" class="todo-del" data-todo-id="{{item.id}}" type="cancel" />
</view>
</view>
</scroll-view>
wxss:
/**index.wxss**/
.todo {
margin: 20rpx;
display: flex;
align-items: center;
background: #F5F5F5;
height: 70rpx;
}
.new-todo {
border: none;
font-style: italic;
width: 100%;
}
.new-todo-save {
font-size: 28rpx
}
.todo-list {
margin: 20rpx;
display: flex;
flex-direction: column;
flex-grow: 2;
}
.todo-item {
display: flex;
height: 80rpx;
position: relative;
}
.todo-check {
margin-top: -6rpx;
}
.todo-del {
margin-top: -6rpx;
position: absolute;
right: 20rpx;
}
.todo-content {
margin-left: 20rpx;
}
.todo-completed {
color: #d9d9d9;
text-decoration: line-through;
}
.todo-footer {
display: flex;
align-items: center;
justify-content: space-between;
height: 80rpx;
margin-left: 20rpx;
margin-right: 20rpx;
font-size: 24rpx;
}
.filter {
display: flex;
flex-direction: row;
}
.filter-item {
margin-left: 10rpx;
padding: 6rpx 14rpx;
}
.filter-active {
border: 1px solid;
border-color: rgba(175, 47, 47, 0.2);
}
.clear-empty {
width: 120rpx;
height: 24rpx;
}