学习 Vue.js:写一个简单的 Todo 小样

这是学习 Vue.js 的一个小样,最后的结果在 codepen.io 上能看到。需要引入 Bootstrap 样式文件和 Vue.js 库。

  1. https://maxcdn.bootstrapcdn.com/bootstrap/...
  2. https://unpkg.com/vue@2.3.4/dist/vue.js

再稍微加点自定义样式。

body {
    margin-top: 20px;
}

.btn-xs+.btn-xs {
    margin-right: .5rem;
}

a.list-group-item.completed {
    background-color: #f5f5f5;
    text-decoration: line-through;
}

架构

HTML

<div id="todoApp" class="container">
    <div class="panel panel-default">
        <div class="panel-heading text-center">
            计划要做的事情,共 0 件
        </div>
        <div class="panel-body">
            <div class="list-groups">
                <a class="list-group-item">
                    ;)
                </a>
            </div>
        </div>
        <div class="panel-footer">
            <form>
                <div class="form-group">
                    <input type="text" class="form-control text-center">
                </div>
                <button class="btn btn-default btn-block" type="submit">添加</button>
            </form>
        </div>
    </div>
</div>

JavaScript

new Vue({
    el: '#todoApp',
    data: {
        todos: [
            {title: '吃早饭', completed: false},
            {title: '吃午饭', completed: false},
            {title: '吃晚饭', completed: false}
        ],
        newTodo: {title: '', completed: false},
    },
    methods: {}
});

循环打印 todos 列表

<div class="panel-heading text-center">
    计划要做的事情,共 {{ todos.length }} 件
</div>

<a class="list-group-item" v-for="(todo, index) in todos">
    {{ todo.title }}
</a>

添加 Todo

<form v-on:submit.prevent="add">
    <div class="form-group">
        <input type="text" class="form-control text-center" v-model="newTodo.title">
    </div>
    <button class="btn btn-default btn-block" type="submit">添加</button>
</form>

input 输入框绑定了 newTodo.title 的值。表单提交时,执行 add 方法。

methods: {
    add() {
        if (! this.newTodo.title.trim()) { return ; }
        this.todos.push({
            title: this.newTodo.title,
            completed: this.newTodo.completed
        });
        this.newTodo.title = '';
    }
}

删除 Todo

<a class="list-group-item"  v-for="(todo, index) in todos">
    {{ todo.title }}
    <button class="btn btn-xs btn-danger pull-right" v-on:click='destroy(index)' title="删除">✘</button>
</a>

点击删除按钮,执行 destroy 方法。

destroy(index) {
    this.todos.splice(index, 1);
}

标记 Todo 完成/未完成

<a class="list-group-item" v-bind:class="{ 'completed': todo.completed }" v-for="(todo, index) in todos">
    {{ todo.title }}
    <button class="btn btn-xs btn-danger pull-right" v-on:click='destroy(index)' title="删除">✘</button>
    <button class="btn btn-xs pull-right" v-on:click='toggleDone(index)' v-bind:class="[todo.completed ? 'btn-success': '']" v-bind:title="[todo.completed ? '点击,标记为未完成': '点击,标记为已完成']">✔</button>
</a>

标记 Todo 使用 toggleDone 方法。

toggleDone(index) {
    this.todos[index].completed = !this.todos[index].completed;
}

上移、下移 Todo

<button class="btn btn-xs btn-info pull-right" v-on:click='down(index)' title="下移">↓</button>
<button class="btn btn-xs btn-info pull-right" v-on:click='up(index)' title="上移">↑</button>

上移

执行 up 方法。

up(index) { 
    if (index - 1 < 0) { return ; }
    var temp = this.todos[index];
    this.todos[index] = this.todos[index-1];
    this.todos[index-1] = temp;
    this.todos = [].concat(this.todos);
}

下移

执行 down 方法。

down(index) {
    if (index + 1 >= this.todos.length) { return ; }
    var temp = this.todos[index];
    this.todos[index] = this.todos[index+1];
    this.todos[index+1] = temp;
    this.todos = [].concat(this.todos);
}

需要注意的是,上移和下移方法中,最后都生成新的 todos,否则数组中元素位置的调整,不会引页面重绘。

this.todos = [].concat(this.todos);
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!