标为完成

324 0 2019年1月7日

用户点击标为完成按钮,则将对应的 todo 标为完成,为了标记 todo 是已完成还是未完成的状态,我们需要稍微改造一下我们的 todo 模型,一开始我们的 todo 有 id、title 两个属性,现在加一个 completed 属性,默认值是 false,表示未完成。

todo = {id:1, title:'todo', completed:false}

当然我们对应的 addTodo 方法也要修改一下:

addTodo: function () {
    this.todos.push(
        // 修改后的 todo 模型
        {id: id++, title: this.newTodoTitle, completed: false}
    );
    this.newTodoTitle = '';
}

标为已完成的思路和之前是一样的,监听用户点击标为完成按钮的 click 事件,然后调用相应的处理方法,把 todo 的 completed 的属性由 false 改为 true 即可。这里的一个关键是,我们如何知道用户点击的是哪一个 todo,或者说我们可以通过坐在用户身边的方式用肉眼观察用户点击了哪个 todo,但是 Vue 如何知道?

好在 Vue 允许我们向绑定的方法传递参数,我们可以把当前循环中 todo 的对象传给绑定的方法,绑定的方法代码如下:

<div id="todo-app">
  ...
  <!--todo list-->
  <ul>
    <li v-for='todo in todos' :key='todo.id'>
      <span>{{ todo.title }}</span>
      <input type="button" 
             value="标为完成"
             @click="markAsCompleted(todo)"/>
      ...
    </li>
  </ul>
  <!-- end todo list -->
  ...
</div>

注意到我们给标为完成的按钮的点击事件绑定了一个 markAsCompleted 方法,这个方法将用来处理将 todo 标为完成的动作。同时和之前绑定的的方法不同的是,我们还给他传递了一个参数,其值为 todo,这个 todo 是我们在 v-for='todo in todos' 获取,当前循环的是哪个 todo,这个 todo 就指向哪个 todo 对象。从而 Vue 就知道了原来我们我们想要操作 todos 列表中这个 todo 对象。

markAsCompleted的逻辑非常简单:

var app = new Vue({
    ...
    methods: {
        addTodo: function () {
            ...
        },
        markAsCompleted: function (todo) {
            todo.completed = true
        }
    }
})

视觉上我们应该让已经标记了已完成的 todo 显示为已删除的状态,一条横线穿过。这需要为我们的内容增加一点样式,这又要用到我们动态绑定样式的方法了:

<li v-for='todo in todos' :key='todo.id'>
    <span :class="{completed: todo.completed}">{{ todo.title }}</span>
    <input type="button" value="标为完成"
           @click="markAsCompleted (todo)"/>
    ...
</li>

这个completed 的样式我们定义在html文档最开头的head标签的style标签里,为元素提供贯穿线的样式。这里根据 todo.completed 来决定是否应该给元素添加 class=‘completed’ 的样式。

练习

练习一:目前我们点击标为完成按钮后,这个按钮是不会消失的,为了更好的用户体验,已完成的 todo 后面不该再显示一个标为完成的按钮了,想办法把它去掉。

练习二:进一步地,如果用户突然发现其实事情还没有做完,他想把这个 todo 标记回未完成状态,添加一个标为未完成的按钮实现这个需求,要注意不同按钮出现的场合应该符合逻辑。

-- EOF --

最后更新:2018-11-11 12:21:12

0 条评论 / 0 人参与