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

说明

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

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

运行效果

查看DEMO

[IMWeb训练营作业]基于Vuejs的Todo List_第1张图片

核心代码

HTML


    <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">
                    
                    <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);

你可能感兴趣的:(vue-js,html,javascript)