[IMWeb训练营作业]基于Vuejs的Todo List

说明

基于Vue的Todo List,提供:
1. 添加任务
2. 编辑任务
3. 删除任务
4. 标记任务完成状态
5. 提供分类视图
6. 提供未完成任务数量

Demo已经上传到Github,欢迎大家和我互相关注:)
https://github.com/winterren/Vue-Demo-Todo-List

运行效果

查看DEMO

screenshot

核心代码

HTML

<!-- 挂载vue的主程序区 -->
    <div class="main">
        <!-- 添加区 -->

        <div class="add-task">
            <div class="container">
                <p>添加任务</p>
                <input 
                    v-model="inputvalue"
                    v-on:keyup.enter="addTodo"
                    type="text" placeholder="按回车确认" class="add-input"
                >
            </div>

        </div>

        <div class="hint-cat">
            <div class="container">
                <!-- 提示 -->
                <div class="hint">
                    <span v-show="list.length">
                        {{ noCheckedLength }}
                        个任务未完成
                    </span>
                </div>
                <!-- 分类 -->
                <div class="category">
                    <ul>
                        <li>
                            <a href="#all">所有</a>
                        </li>
                        <li>
                            <a href="#completed">已完成</a>
                        </li>
                        <li>
                            <a href="#uncompleted">未完成</a>
                        </li>
                    </ul>
                </div>
            </div>

        </div>


        <!-- 显示区 -->
        <div class="tasks">
            <div class="container">
                <span v-show="!list.length">还没有添加任何任务</span>
                <ul class="todo-list">
                    <!-- 从vue渲染进来 -->
                    <li class="todo" v-bind:class="{completed:item.isChecked, editing:item===editing}" 
                        v-for="item in filterList">
                        <div class="view">
                            <input type="checkbox"  class="toggle" v-model="item.isChecked">
                            <label v-on:dblclick="edit(item)">{{item.title}}</label>
                            <button class="destroy" v-on:click="deleteTodo(item)">×</button>
                        </div>
                        <input 
                            v-focus="item===editing" 
                            type="text" 
                            class="edit" 
                            v-model="item.title" 
                            v-on:blur="edited(item)"
                            v-on:keyup.13="edited(item)"
                            v-on:keyup.esc="cancel(item)"
                        >
                    </li>

                </ul>
            </div>
        </div>
    </div>

JS

//存取localStorage
var storage = {
    save(key,value){
        // 把value转成字符串
        localStorage.setItem(key,JSON.stringify(value));
    },
    fetch(key){
        return JSON.parse(localStorage.getItem(key)) || [];
    }
}

// 数据格式
var defaultlist = [
    {
        title:"起床",
        isChecked:true
    },
    {
        title:"睡觉",
        isChecked:false
    }
];
storage.save("mystorage",defaultlist)

var list = storage.fetch("mystorage");
//过滤时考虑三种情况all completed uncompleted
var filter = {
    all:function(){
        return list;
    },
    completed:function(){
        return list.filter(function(item){
            return item.isChecked;
        })
    },
    uncompleted:function(){
        return list.filter(function(item){
            return !item.isChecked;
        })
    }
}


// 实例化
var vm = new Vue({
    // 挂载点
    el: ".main",
    // 挂载数据
    data:{
        list: list,
        inputvalue: "", //记录将要添加的数据
        editing:'' ,    //记录正在编辑的数据
        beforeEdit:'',  //记录正在编辑的数据的title
        visibility:"all"//
    },
    watch:{
        list:{
            handler:function(){
                // list变化时执行函数
                storage.save("mystorage",this.list)
            },
            deep:true
        }
    },
    computed:{
        noCheckedLength:function(){
            return this.list.filter(function(item){
                        return !item.isChecked;
                    }).length
        },
        filterList:function(){

            return filter[this.visibility] ? filter[this.visibility](list):list;

        }
    },
    methods:{
        addTodo(e){ //添加任务
            this.list.unshift({
                title: this.inputvalue,
                isChecked: false
            })

            this.inputvalue=""
        },
        deleteTodo(todo){//删除任务
            var index = this.list.indexOf(todo);
            this.list.splice(index,1)
        },
        edit(item){//编辑任务
            //先记录下来编辑前的title,方便esc取消后能重新赋值
            this.beforeEdit = item.title;
            this.editing = item;
        },
        edited(item){//完成编辑
            this.editing = '';
        },
        cancel(item){//取消
            item.title = this.beforeEdit;
            this.editing = '';
        }
    },
    directives:{
            focus:{
                update: function(el,binding){
                    if(binding.value){
                        el.focus();
                    }
                }
            }
        }
})

function watchHashChange(){
    var hash = window.location.hash.slice(1);
    vm.visibility = hash;
}
watchHashChange();
window.addEventListener("hashchange",watchHashChange);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值