美文网首页
vue 构建 todo 项目系列1

vue 构建 todo 项目系列1

作者: 闲睡猫 | 来源:发表于2019-10-14 16:22 被阅读0次

    todo 即个人事务管理项目,很适合 vue 练手,本系列课程将从零开始演示如何用 vue 构建一个简易的 todo 项目

    初始化项目

    todomvc 提供了多种技术栈实现方案,可以直接下载源码学习,也可以下载 静态资源模板, 然后自己写业务逻辑代码

    $ git clone https://github.com/tastejs/todomvc-app-template.git
    
    $ cnpm install
    

    访问主页,效果如下:

    image

    接下来要在项目中初始化 vue

    首先在 index.html 中引入 vue

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <section id="todoapp" class="todoapp">
        <h1>{{ title }}</h1>
        <!-- ... -->
    </section>
    

    然后将 app.js 改为:

    // 自调用匿名函数的最大用处就是封装作用域
    (function (vue) {
        let app = new Vue({
            el: "#todoapp",
            data: {
                title: 'Todotest'
            },
            methods: {
    
            }
        })
    })(Vue);
    

    访问页面,可看到 vue 可成功引入, 页面标题已被 vue 绑定

    image

    源码

    任务展示

    app.js 中添加模拟数据:

        // 模拟数据
        const list_data = [
            {id: 1, title: 'one', stat: true},
            {id: 2, title: 'two', stat: false},
            {id: 3, title: 'three', stat: true},
        ]
        let app = new Vue({
            el: "#todoapp",
            data: {
                title: 'Todotest',
                list_data
            }
        })
    

    index.html 展示数据,并根据是否有数据加载节点

    <!-- 数据存在时才加载以下节点 -->
    <template v-if="list_data.length">
        <section class="main">
            <!-- .... -->
            <!-- 遍历数据 -->
            <li v-for="(v,k) in list_data" class="completed">
                <div class="view">
                    <input class="toggle" type="checkbox" checked>
                    <label>{{ v.title }}</label>
                    <button class="destroy"></button>
                </div>
                <input class="edit" value="Create a TodoMVC template">
            </li>
        </section>
        <!-- .... -->
    </template>
    
    image

    源码

    添加任务

    index.html 绑定 enter 事件

    <input class="new-todo" @keyup.enter="addTodo" placeholder="What needs to be done?" autofocus>
    

    app.js 将新增的数据追加到数组中

    methods: {
        addTodo(ev) {
            // 获取节点对象的文本框内容
            let title = ev.target.value
            let id = this.list_data[this.list_data.length - 1]['id'] + 1
            let stat = false
            this.list_data.push({id, title, stat})
            // 重置文本框
            ev.target.value = ''
        }
    }
    
    image

    源码

    任务的全选与全不选

    image

    index.html 绑定 click 事件

    <input id="toggle-all" @click="toggleAll" class="toggle-all" type="checkbox">
    
    <li v-for="(v,k) in list_data" class="completed">
        <!-- 选中状态的双向绑定 -->
        <input class="toggle" type="checkbox" v-model="v.stat">
    </li>
    

    app.js 新增以下方法

    // 任务的状态与全选按钮的状态一致
    toggleAll(ev) {
        for (let i=0; i<this.list_data.length; i++) {
            this.list_data[i].stat = ev.target.checked
        }
    }
    

    源码

    不同状态下的任务样式

    image

    不同状态下的任务样式是不同的,根据 stat 属性进行判断,修改 index.html:

    <li v-for="(v,k) in list_data" :class="{completed: v.stat}">
        <!--  -->
    </li>
    

    源码

    删除任务

    image

    index.html 绑定 click 事件

    <button @click="removeTodo(k)" class="destroy"></button>
    

    app.js 删除数据

    removeAllDone() {
        // 删除任务的几种实现方式
        // for 循环
        // for (let i=0; i<this.list_data.length; i++) {
        //  if (this.list_data[i].stat === true) {
        //      this.list_data.splice(i, 1)
        //  }
        // }
    
        // 过滤器
        // this.list_data = this.list_data.filter(function(item) {
        //  if (item.stat === false) {
        //      return item
        //  }
        // })
    
        // es6 简写语法
        this.list_data = this.list_data.filter((v)=>!v.stat)
    }
    

    源码

    空字符串不触发任务添加

    现在的程序有个 bug, 添加任务时如果直接按 enter 或者只输入空格,都能触发任务添加,需要在数据添加前进行过滤

    index.html 绑定 enter 事件

    <input class="new-todo" @keyup.enter="addTodo" placeholder="What needs to be done?" autofocus>
    

    app.js 过滤数据

    addTodo(ev) {
        // 获取节点对象的文本框内容
        let title = ev.target.value.trim()
        if (title === '') {
            return ;
        }
        // ...
    }
    

    源码

    原文:https://www.itshutong.com/347.html

    相关文章

      网友评论

          本文标题:vue 构建 todo 项目系列1

          本文链接:https://www.haomeiwen.com/subject/ybirmctx.html