20_TodoList案例
20_TodoList案例
组件化编码流程(通用)
1.实现静态组件:抽取组件,使用组件实现静态页面效果2.展示动态数据:2.1.数据的类型、名称是什么?2.2.数据保存在哪个组件?3.交互——从绑定事件监听开始
图示
代码演示
App.vue
<template><div id="root"><div class="todo-container"><div class="todo-warp"><MyHeader :addTodo="addTodo" /><List :todos="todos" :checkTodo="checkTodo" :deleteTodo="deleteTodo" /><MyFooter:todos="todos":checkAllTodo="checkAllTodo":clearAllTodo="clearAllTodo"/></div></div></div>
</template><script>
import MyHeader from "./components/MyHeader";
import MyFooter from "./components/MyFooter";
import List from "./components/List";
export default {name: "App",components: {MyHeader,MyFooter,List,},data() {return {todos: [{ id: "001", title: "吃饭", done: true },{ id: "002", title: "学习", done: false },{ id: "003", title: "打球", done: true },],};},methods: {//增加一个todoaddTodo(todoObj) {this.todos.unshift(todoObj);},//勾选or取消一个todocheckTodo(id) {this.todos.forEach((todo) => {if (todo.id == id) todo.done = !todo.done;});},//删除一个tododeleteTodo(id) {this.todos = this.todos.filter((todo) => {return todo.id !== id;});},//全选or全不选checkAllTodo(done) {this.todos.forEach((todo) => {todo.done = done;});},//清除所有已完成的todoclearAllTodo() {this.todos = this.todos.filter((todo) => {return !todo.done;});},},
};
</script>
<style>
/*base*/
body {background-color: #fff;
}
.btn {display: inline-block;padding: 4px 12px;margin-bottom: 0;font-size: 14px;line-height: 20px;text-align: center;vertical-align: middle;cursor: pointer;box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2 px rgba(0, 0, 0, 0.05);border-radius: 4px;
}
.btn-danger {color: #fff;background-color: #da4f49;border: 1px solid #bd362f;
}.btn-danger:hover {color: #fff;background-color: #bd362f;
}
.btn:focus {outline: none;
}
.todo-container {width: 600px;margin: 0 auto;
}
.todo-container .todo-warp {padding: 10px;border: 1px solid #ddd;border-radius: 5px;
}
</style>
MyHeader.vue
<template><div class="todo-header"><inputtype="text"placeholder="请输入你的任务名称,按回车键确认" v-model="title"@keyup.enter="add"/></div>
</template><script>
export default {name: "MyHeader",props:['addTodo'],data() {return {title:''}},methods: {add() {if(!this.title.trim) return//将用户的输入包装成一个todo对象const todoObj = { id: Math.random(), title: this.title, done: false };//通知app组件去添加一个todo对象this.addTodo(todoObj);this.title=''},},
};
</script><style>
/*header*/
.todo-header input {width: 560px;height: 28px;font-size: 14px;border: 1px solid #ccc;border-radius: 4px;padding: 4px 7px;
}
.todo-header input:focus {outline: none;border-color: rgba(82, 168, 236, 0.8);box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 8px rgba(82, 168, 236, 0.6);
}
</style>
List.vue
<template><ul class="todo-main"><Itemv-for="todoObj in todos":key="todoObj.id":todo="todoObj":checkTodo="checkTodo":deleteTodo="deleteTodo"/></ul>
</template><script>
import Item from "./Item";
export default {name: "List",components: {Item,},props: ["todos", "checkTodo","deleteTodo"],
};
</script><style scoped>
/* main */
.todu-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;
}
.tode-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;
}
</style>
Item.vue
<template><li><label><input type="checkbox" :checked="todo.done" @change="handleCheck(todo.id)"/><span>{{todo.title}}</span></label><button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button></li>
</template><script>
export default {name: "Item",props:['todo','checkTodo','deleteTodo'],methods:{handleCheck(id){this.checkTodo(id);},handleDelete(id){if(confirm('确认删除吗?')){this.deleteTodo(id);}}}
};
</script><style scoped>
/* item */
li {list-style: none;height: 36px;line-height: 36px;padding: 0 5px;border-bottom: 1px solid #ddd;
}li label {float: left;cursor: pointer;
}li babel li input {vertical-align: middle;margin-right: 6px;position: relative;top: -1px;
}li button {float: right;display: none;margin-top: 3px;
}
li:before {content: initial;
}
li:last-child {border-bottom: none;
}
li:hover{background-color: #ddd;
}
li:hover button{display: block;
}</style>
MyFooter.vue
<template><div class="todo-footer" v-show="total"><label><!-- <input type="checkbox" :checked="isAll" @change="checkAll"/> --><input type="checkbox" v-model="isAll"/></label><span><span>已完成{{ doneTotal }}</span> /全部{{ total }}</span><button class="btn btn-danger" @click="clearAll">清除已完成任务</button></div>
</template><script>
export default {name: "MyFooter",props: ["todos","checkAllTodo","clearAllTodo"],computed: {total() {return this.todos.length;},doneTotal() {return this.todos.reduce((pre, current) => {return pre + (current.done ? 1 : 0);}, 0);},isAll:{get(){return this.doneTotal === this.total && this.total > 0},set(value){this.checkAllTodo(value) }}},methods:{checkAll(e){this.checkAllTodo(e.target.checked)},clearAll(){this.clearAllTodo()}}
};
</script><style>
/*footer*/
.todo-footer {height: 40px;line-height: 40px;padding-left: 6px;margin-top: 5px;
}
.todo-footer label {display: inline-block;margin-right: 20px;cursor: pointer;
}
.todo-footer label input {position: relative;top: -1px;vertical-align: middle;margin-right: 5px;
}
.todo-footer button {float: right;margin-top: 5px;
}
</style>
TodoList案例小总结
1.组件化编码流程:(1).拆分静态组件;组件要按照功能点拆分,命名不要与html元素冲突。(2).实现动态组件;考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:1).一个组件在用:放在组件自身即可。2).一些组件在用:放在他们共同的父组件上(状态提升)。 (3).实现交互:从绑定事件开始。2. props适用于:(1).父组件==>子组件通信(2).子组件==>父组件通信(要求父先给子一个函数)3.使用v-model时要切记: v-model绑定的值不能是props传过来的值,因为props是不可以修改的!4.props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。
20_TodoList案例相关推荐
- python 网络编程之Socket通信案例消息发送与接收
背景 网络编程是python编程中的一项基本技术.本文将实现一个简单的Socket通信案例消息发送与接收 正文 在python中的socket编程的大致流程图如上所示 我们来首先编写客户端的代码: # ...
- 2021年大数据ELK(十七):Elasticsearch SQL 订单统计分析案例
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 订单统计分析案例 一.案例介绍 二.创建索引 三.导入测试数据 四.统计不同支 ...
- 2021年大数据ELK(十六):Elasticsearch SQL(职位查询案例)
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 职位查询案例 一.查询职位索引库中的一条数据 二.将SQL转换为DSL 三.职 ...
- 2021年大数据ELK(四):Lucene的美文搜索案例
全网最详细的大数据ELK文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 美文搜索案例 一.需求 二.准备工作 1.创建IDEA项目 2. ...
- ❤️让人心跳加速的陌陌案例,大数据必需学会的基础案例!❤️ 【推荐收藏】
全网最详细的大数据HBase文章系列,强烈建议收藏加关注! 已列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 前言 陌陌案例 一.陌陌案例的需求说明 二.陌陌案例中表设计内容 1. ...
- 2021年大数据Hive(十二):Hive综合案例!!!
全网最详细的大数据Hive文章系列,强烈建议收藏加关注! 新文章都已经列出历史文章目录,帮助大家回顾前面的知识重点. 目录 系列历史文章 前言 Hive综合案例 一.需求描述 二.项目表的字段 三.进 ...
- 2021年大数据Flink(三十八):Table与SQL 案例五 FlinkSQL整合Hive
目录 案例五 FlinkSQL整合Hive 介绍 集成Hive的基本方式 准备工作 1.添加hadoop_classpath 2.下载jar并上传至flink/lib目录 3.修改hive配置 4.启 ...
- 2021年大数据Flink(三十七):Table与SQL 案例四
目录 案例四 需求 代码实现 案例四 需求 从Kafka中消费数据并过滤出状态为success的数据再写入到Kafka {"user_id": "1", &qu ...
- 2021年大数据Flink(三十六):Table与SQL 案例三
目录 案例三 需求 编码步骤 代码实现-方式1 代码实现-方式2 案例三 需求 使用Flink SQL来统计5秒内 每个用户的 订单总数.订单的最大金额.订单的最小金额 也就是每隔5秒统计最近5秒的每 ...
最新文章
- 链表问题2——在双链表中删除倒数第K个节点
- linux集群-keepalived介绍-用keepalived配置高可用集群
- 关于购买企业邮箱,谨防陷入几大误区
- Vue系列vue-router的配置使用(一)
- mysql导入社工库文件_社工库-数据表结构设计和数据导入
- pytorch学习笔记(十七):Read-Write
- idea eclipse主题
- 思科为计算机配置ip命令,cisco路由器配置命令练习
- 吴恩达机器学习笔记——线性代数知识回顾、梯度下降、多项式线性回归、正则方程
- java.net.ConnectException: no available server
- KEIL识别不出野火STM32仿真器问题解决
- 关于Mac系统 使用npm i xxx的时候 报错
- 英语老师自用省心天花板小程序
- Wordpress搭建笔录
- 华擎主板的网络唤醒设置。
- PHP5.4 如何连接MS Sql Server
- 天津达内聊H5 软键盘兼容方案
- Basic Level 1035 插入与归并 (25分)
- STM32驱动1.44TFT显示屏
- 【博客523】k8s修改pod的内核参数以优化服务网络性能