【IMWeb训练营作业】vue demo Todolist

【IMWeb训练营作业】vue demo Todolist

学习计划

【每日学习】
1、早上6:00-9:00,签到-每天早起计划;
2、早上9:00,每天看一节录播课;
https://ke.qq.com/course/200811
3、下午14:00,每天碎片化读一篇文;
https://zhuanlan.zhihu.com/imweb
4、晚上8:00-10:00,每晚交流2小时。
Ps:腾讯导师直播课一共3次,分别为17、18、21号晚8点半
【作业任务】
第一次(个人,19号):完成todo list;
第二次(个人,21号):完成组件select;
第三次(小组,24号):用Vue实现一款常用的APP/网站的部分页面。

建议:
不推荐上来就直接用 vue-cli脚手架构建项目,特别是没了解过 Node/Webpack /es6。
通读官方文档+这个todolist小demo,就基本入门了
不多说了,直接进入主题,直接上效果图

效果

运行后的效果图

知识点

(1)在本地的todos .html 文件,通过如下方式引入 Vue:

<script src="./vue.js"></script>

提示:在开发时请用开发版本,遇到常见错误它会给出友好的警告。
官方文档传送门:https://cn.vuejs.org/v2/guide/installation.html

(2)v-model:用法:在表单控件或者组件上创建双向绑定。

<input placeholder="例如:吃饭睡觉打豆豆;    提示:+回车即可添加任务" 
            class="task-input" 
            type="text"
            v-model="todo"
            @keyup.13="addTodo"/>
<input class="toggle" type="checkbox" v-model="item.isChecked" />

提示:限制以下使用

<input>
<select>
<textarea>
components

官方文档传送门:https://cn.vuejs.org/v2/api/#v-model

(2)v-on:用法:绑定事件监听器。事件类型由参数指定。表达式可以是一个方法的名字或一个内联语句,如果没有修饰符也可以省略。用在普通元素上时,只能监听 原生 DOM 事件。用在自定义元素组件上时,也可以监听子组件触发的自定义事件,缩写为“@”

<input v-foucs="edtorTodos === item" class="edit" type="text" 
 v-model = "item.title" @blur="edtorTodoed(item)"
                        @keyup.13="edtorTodoed(item)"
                        @keyup.esc="cancelTodo(item)"/>

官方文档传送门:https://cn.vuejs.org/v2/api/#v-on

(3)v-show:用法:根据表达式之真假值,切换元素的 display CSS 属性。当条件变化时该指令触发过渡效果。

<span class="no-task-tip" v-show="!list.length">还没有添加任何任务</span>

官方文档传送门:https://cn.vuejs.org/v2/api/#v-show

(5)v-bind:动态地绑定一个或多个特性,或一个组件 prop 到表达式。
在绑定 class 或 style 特性时,支持其它类型的值,如数组或对象。可以通过下面的教程链接查看详情。
在绑定 prop 时,prop 必须在子组件中声明。可以用修饰符指定不同的绑定类型。
没有参数时,可以绑定到一个包含键值对的对象。注意此时 class 和 style 绑定不支持数组和对象。缩写为“:”

<li class="todo" :class="{completed: item.isChecked,editing: item === edtorTodos}" v-for="item in filteredList"/>

官方文档传送门:https://cn.vuejs.org/v2/api/#v-bind

(6)v-for:列表渲染,用v-for指令根据一组数组的选项列表进行渲染。 v-for指令需要以item in items形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名。

<li class="todo" :class="{completed: item.isChecked,editing: item === edtorTodos}" v-for="item in filteredList"/>

官方文档传送门:https://cn.vuejs.org/v2/api/#v-for

(7)filter:过滤器

var filter = {
    all:function (list) {
        return list;
    },
    finished:function (list) {
        return list.filter(function (item) {
            return item.isChecked;
        })
    },
    unfinish:function () {
        return list.filter(function (item) {
            return !item.isChecked;
        })
    }
}

代码块

todos.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="index.css">
    <script src="./vue.js"></script>
</head>
<body>
    <div class="page-top">
        <div class="page-content">
            <h2>任务计划列表</h2>
        </div>
    </div>
    <div class="main">
        <h3 class="big-title">添加任务:</h3>
        <input 
            placeholder="例如:吃饭睡觉打豆豆;    提示:+回车即可添加任务" 
            class="task-input" 
            type="text"
            v-model="todo"
            @keyup.13="addTodo"
        />
        <ul class="task-count" v-show="list.length">
            <li>{{noCheckeLength}}个任务未完成</li>
            <li class="action">
                <a class="active" href="#all">所有任务</a>
                <a href="#unfinish">未完成的任务</a>
                <a href="#finished">完成的任务</a>
            </li>
        </ul>
        <h3 class="big-title">任务列表:</h3>
        <div class="tasks">

            <span class="no-task-tip" v-show="!list.length">还没有添加任何任务</span>
            <ul class="todo-list">
                <li class="todo" :class="{completed: item.isChecked,editing: item === edtorTodos}" v-for="item in filteredList"/>
                    <div class="view">
                        <input class="toggle" type="checkbox" v-model="item.isChecked" />
                        <label @dblclick="edtorTodo(item)">{{ item.title }}</label>
                        <button class="destroy" @click="deleteTodo(item)"></button>
                    </div>
                    <input 
                        v-foucs="edtorTodos === item" 
                        class="edit" 
                        type="text" 
                        v-model = "item.title"
                        @blur="edtorTodoed(item)"
                        @keyup.13="edtorTodoed(item)"
                        @keyup.esc="cancelTodo(item)" />
                </li>
            </ul>
        </div>
    </div>
    <script src="app.js"></script>
</body>
</html>

app.js

var storage={
    save(key,value){
        localStorage.setItem(key,JSON.stringify(value));
    },
    fetch(key){
        return JSON.parse(localStorage.getItem(key))||[];
    }
};
var list = storage.fetch("todo-class");
var filter = {
    all:function (list) {
        return list;
    },
    finished:function (list) {
        return list.filter(function (item) {
            return item.isChecked;
        })
    },
    unfinish:function () {
        return list.filter(function (item) {
            return !item.isChecked;
        })
    }
}
var vm = new Vue({
    el:".main",
    data:{
        list:list,
        todo:"",
        edtorTodos:'',  //记录正在编辑的数据
        beforeTitle:'', //记录正在编辑的数据的title
        visibility:"all"
    },
    watch:{
        list:{
            handler:function () {
                storage.save("todo-class",this.list);
            },
            deep:true
        }
    },
    computed:{
        noCheckeLength:function(){
            return this.list.filter(function(item){
                return !item.isChecked
            }).length
        },
        filteredList:function () {

            return filter[this.visibility] ? filter[this.visibility](list) : list;
        }
    },
    methods:{
        addTodo(){  //添加任务
            this.list.push({
                title:this.todo,
                isChecked:false
            });
            this.todo = '';
        },
        deleteTodo(todo){ //删除任务
            var index = this.list.indexOf(todo);
            this.list.splice(index,1);
        },
        edtorTodo(todo){  //编辑任务
            console.log(todo);
            //编辑任务的时候,记录一下编辑这条任务的title,方便在取消编辑的时候重新给之前的title
            this.beforeTitle = todo.title;

            this.edtorTodos = todo;


        },
        edtorTodoed(todo){ //编辑任务成功
            this.edtorTodos = '';
        },
        cancelTodo(todo){  //取消编辑任务

            todo.title = this.beforeTitle;

            this.beforeTitle = '';

            //让div显示出来,input隐藏
            this.edtorTodos = '';
        }
    },
    directives:{
        "foucs":{
            update(el,binding){
                if(binding.value){
                    el.focus();
                }
            }
        }
    }
});

function watchHashChange() {
    var hash = window.location.hash.slice(1);
    vm.visibility = hash;
}
watchHashChange();
window.addEventListener("hashchange",watchHashChange)

最后附上源码:https://github.com/git641395399/todolist

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值