尚硅谷todolist案例
vue todolist案例
1 拆分组件
一共拆分为4个组件
TodoHeader
TodoItem
TodoList
TodoFooter
item是list的子组件
2 组件化编码流程
实现静态组件:抽取组件,只考虑结构和样式
先拆结构再拆样式
展示动态数据
使用数组对象来保存数据[{},{},{}]
每一个对象的{
id:
name:
ok:
…
}
谁展示对象,就保存在哪个组件,这里保存在list里面
3 交互-添加一个todo
- 将要添加的todo包装成一个对象
- 需要把header中的todoObj添加到list上
问题:现知识无法实现,因为header和list没有父子关系,是兄弟关系
解决方法(初级):
将todos[]放在app中,通过props去传递
在将todo传递给header(子级给父级传)
提前在app里提前准备好methods,设置接收方法receive()
把receive()交给header 【app是父亲可以给孩子传函数(方法),数组,字符串,布尔值…都行】
然后在header中使用props接收receive,此时receive出现在header组件的实例vc上,模板就可以直接用
静态数组不能重名–>addTodo 不可以写成add
组件间通信
父亲给儿子传 儿子给父亲传
4 交互-todos勾选
实现勾选操作数据也会发生变化
思路:拿到勾选框的id,再到todos里找到勾选的todo,将done值取反
- 给勾选框绑定change()事件
数据再哪里,对数据的操作就写在哪里
todos在App组件中,所以对todos的增删改查都应写在app组件中
在app中写checkTodo(id)方法
- 此时是app爷爷向item孙子传
- 一步一步逐层传递
<!-- :checked="true" 如果后面属性是true就勾选 --><!-- 如下代码也能实现功能,但不太推荐,因为有点违反原则,修改了props --><inputtype="checkbox"v-model="todo.done"/>
v-model绑定的是布尔值,输入框是checkbox,那么这个布尔值可以确定checkbox勾或者不勾
因为传入的todo是通过props,props只读不可以修改(栈里面的地址没变,变的是堆里面存的数据),vue监测的是引用地址,只要地址不变,就没修改
使用v-model更改数据是藏在对象中改,vue检测不到
所以v-model不建议使用props传入的数据
5 交互-todos删除
点击删除按钮,拿到按钮的id
todos在App中,所以在item中要通知App删除对象
在App中写删除方法deleteTodo()
爷传孙,先给list,在list给item
6 交互-todos底部统计
todos的长度就是全部的数量
在遍历todos中done值为真的todo
统计已完成的事项
方法一:遍历
let i = 0;this.todos.forEach((todo) => {if (todo.done) i++;});return i;
方法二:reduce()
const x = this.todos.reduce((pre, current) => {console.log("@", pre, current);return pre + (current.done ? 1 : 0);}, 0);
return this.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0);
7 交互-todos底部统计
拿到已完成的事项与总计事项作比较,相等且总数事项>0 ,勾选已完成勾选框
一个计算属性可以通过其他计算属性再进行计算
当页面没有展示的todos时,隐藏footer,使用v-show='total’判断total的布尔值
点击已完成勾选框,事项都勾选,到App中写全选和全不选的方法
红色:初始化展示,绿色:交互
可以使用v-model,使用getter和setter完整的写法
<input type="checkbox" v-model="isAll" />
isAll: {//全选框是否勾选get() {return this.doneTotal === this.total && this.total > 0;},//isAll被修改时set被调用set(value) {this.checkAllTodo(value);},},
- 清除已完成
总结TodoList案例
- 组件化编码流程:
(1).拆分静态组件:组件要按照功能点
拆分,命名不要与html元素冲突。
(2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
1).一个组件在用:放在组件自身即可。
2). 一些组件在用:放在他们共同的父组件上(状态提升)。
(3).实现交互:从绑定事件开始。
- props适用于:
(1).父组件 ==> 子组件 通信
(2).子组件 ==> 父组件 通信(要求父先给子一个函数)
使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!
props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。
实例代码
app.vue
<template><div id="root"><div class="todo-container"><div class="todo-wrap"><todo-header :addTodo="addTodo"></todo-header><todo-list:todos="todos":checkTodo="checkTodo":deleteTodo="deleteTodo"></todo-list><todo-footer:todos="todos":checkAllTodo="checkAllTodo":clearDoneTodo="clearDoneTodo"></todo-footer></div></div></div>
</template><script>
// 引入
import TodoHeader from "./components/TodoHeader.vue";
import TodoList from "./components/TodoList.vue";
import TodoFooter from "./components/TodoFooter.vue";// 注册
export default {name: "App",components: {TodoHeader,TodoList,TodoFooter,},data() {return {//由于todos是MyHeader组件和MyFooter组件都在使用,所以放在App中(状态提升)todos: [{ id: "001", title: "吃饭", done: true },{ id: "002", title: "睡觉", done: false },{ id: "003", title: "喝酒", done: true },],};},methods: {// 添加一个todoaddTodo(todoObj) {// 操作数据往数组前方加数据this.todos.unshift(todoObj);},// 勾选、取消勾选todocheckTodo(id) {// 拿到todos遍历todo项this.todos.forEach((todo) => {if (todo.id == id) todo.done = !todo.done;});},// 删除一个tododeleteTodo(id) {this.todos = this.todos.filter((todo) => todo.id !== id);},// 全选或者全不选checkAllTodo(done) {this.todos.forEach((todo) => {todo.done = done;});},// 清除所有已完成的todoclearDoneTodo() {this.todos = this.todos.filter((todo) => {return !todo.done;});},},
};
</script><style scoped>
/*base*/
body {background: #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 2px 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-wrap {padding: 10px;border: 1px solid #ddd;border-radius: 5px;
}
</style>
TodoFooter.vue
<template><div class="todo-footer" v-show="total"><label><!-- <input type="checkbox" :checked="isAll" @change="checkAll" /> --><!-- 使用v-model --><input type="checkbox" v-model="isAll" /></label><span><span>已完成{{ doneTotal }}</span> / 全部{{ total }}</span><button class="btn btn-danger" @click="clearDone">清除已完成任务</button></div>
</template><script>
export default {name: "TodoFooter",props: ["todos", "checkAllTodo", "clearDoneTodo"],computed: {//总数total() {return this.todos.length;},//计算已完成数doneTotal() {// 遍历let i = 0;this.todos.forEach((todo) => {if (todo.done) i++;});return i;//此处使用reduce方法做条件统计// 最后一个返回值作为reduce的返回值/* const x = this.todos.reduce((pre, current) => {console.log("@", pre, current);return pre + (current.done ? 1 : 0);}, 0); *//* return this.todos.reduce((pre, todo) => pre + (todo.done ? 1 : 0), 0); */},/* isAll() {// 总数大于零并且相等return this.doneTotal === this.total && this.total > 0;}, *///控制全选框isAll: {//全选框是否勾选get() {return this.doneTotal === this.total && this.total > 0;},//isAll被修改时set被调用set(value) {this.checkAllTodo(value);},},},methods: {/* checkAll(e) {this.checkAllTodo(e.target.checked);}, *///清空所有已完成clearDone() {this.clearDoneTodo();},},
};
</script><style scoped>
/*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>
TodoHeader.vue
<template><div class="todo-header"><!-- @keyup.enter="add":按下enter添加add()方法 --><inputtype="text"placeholder="请输入你的任务名称,按回车键确认"v-model="title"@keyup.enter="add"/></div>
</template><script>
// 引入nanoid生成唯一字符串给id
import { nanoid } from "nanoid";
export default {name: "TodoHeader",props: ["addTodo"],data() {return {title: "",};},methods: {add() {// 将用户的输入包装成todo对象// 校验数据if (!this.title.trim()) return alert("输入不能为空");//将用户的输入包装成一个todo对象// nanoid() 生成全球唯一字符串const todoObj = { id: nanoid(), title: this.title, dnoe: false };// 通知App组件去添加ToDO对象this.addTodo(todoObj);// 成功输入完添加后输入框变为空this.title = "";},// 接受App传过来的参数},
};
</script><style scoped>
/*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>
TodoItem.vue
<template><li><label><!-- :checked="true" 如果后面属性是true就勾选 --><!-- 如下代码也能实现功能,但不太推荐,因为有点违反原则,修改了props --><inputtype="checkbox":checked="todo.done"@change="handleCheck(todo.id)"/><!-- 展示todo事项的名字 --><span>{{ todo.title }}</span></label><button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button></li>
</template><script>
export default {name: "TodoItem",// 声明接收父容器todoList传来的对象props: ["todo", "checkTodo", "deleteTodo"],methods: {// 勾选handleCheck(id) {// 通知App组件将对应的todo对象值取反this.checkTodo(id);},// 删除handleDelete(id) {if (confirm("确认删除吗?")) {//通知App组件将对应的todo对象删除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 label 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>
TodoList.vue
<template><ul class="todo-main"><!-- v-for="todoObj in todos" :遍历todos的对象:key="todoObj.id" 使用id作为索引变量--><todo-itemv-for="todoObj in todos":key="todoObj.id":todo="todoObj":checkTodo="checkTodo":deleteTodo="deleteTodo"></todo-item></ul>
</template><script>
// 引入item
import TodoItem from "./TodoItem.vue";
export default {name: "TodoList",components: {TodoItem,},//声明接收App传递过来的数据,其中todos是自己用的,checkTodo和deleteTodo是给子组件MyItem用的props: ["todos", "checkTodo", "deleteTodo"],
};
</script><style scoped>
/*main*/
.todo-main {margin-left: 0px;border: 1px solid #ddd;border-radius: 2px;padding: 0px;
}.todo-empty {height: 40px;line-height: 40px;border: 1px solid #ddd;border-radius: 2px;padding-left: 5px;margin-top: 10px;
}
</style>
尚硅谷todolist案例相关推荐
- hive尚硅谷实战案例统计youtube视频热度
hive视频热度统计案例 文章目录 hive视频热度统计案例 背景及需求描述 项目的完成 1. 数据清洗 (1) maven依赖 (2)ETLUtils-处理具体的数据清洗逻辑 (3)ETLMappe ...
- 尚硅谷github案例
引入第三方bootstrap,要在public文件下的index.html中用link引入(且用相同的BAS_URl),如果在App.vue中引入会出现错误. Search组件(搜索栏) 引入axio ...
- 02尚硅谷书城案例-用户的注册
1.JavaEE 项目的三层架构 2.先创建书城需要的数据库和表 drop database if exists book; create database book; CREATE TABLE t_ ...
- 尚硅谷大数据技术Spark教程-笔记09【SparkStreaming(概念、入门、DStream入门、案例实操、总结)】
尚硅谷大数据技术-教程-学习路线-笔记汇总表[课程资料下载] 视频地址:尚硅谷大数据Spark教程从入门到精通_哔哩哔哩_bilibili 尚硅谷大数据技术Spark教程-笔记01[SparkCore ...
- 【视频分享】尚硅谷HTML5前端视频_Vue核心技术视频
本视频基于Vue2.5录制, 涵盖Vue开发所需技术: 模板.数据绑定.声明式渲染.计算属性.事件处理.过渡动画.指令.自定义Vue插件.组件化开发.组件间通信.Ajax前后台交互.Vue-Route ...
- 尚硅谷大数据视频_Shell视频教程
Shell是一个功能相当强大的编程语言,易编写.易调试.灵活性强.Shell可以帮助我们来管理大数据集群,提高开发效率.本课程详细讲解:Shell解析器.变量.运算符.条件判断.流程控制.函数.cut ...
- ToDoList 案例完整 尚硅谷
总结ToDoList案例: 1.组件化编码流程: (1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突. (2).实现动态组件:考虑好数据的存放位置,数据是一个组件再用,还是一些组件 ...
- 尚硅谷Redis6基础教程-秒杀案例中库存遗留问题
尚硅谷redis6基础教程中视频24-27的秒杀案例,使用Redis乐观锁解决了超卖问题,但是也产生了库存遗留问题.引入Lua脚本,解决了超卖和库存遗留.Lua脚本为什么解决了库存遗留问题???
- 【HBase学习笔记-尚硅谷-Java API shell命令 谷粒微博案例】
HBase学习笔记 HBase 一.HBase简介 1.HBase介绍 2.HBase的逻辑结构和物理结构 3.数据模型 4.基本架构 二.快速入门 1.配置HBase 2.命令 三.API 1.获取 ...
最新文章
- C/C++反序输出字符串总结
- 如何备份被独占文件?
- Angular中父组件通过ViewChild调用子组件的方法
- JavaScript实现isPowerOfTwo算法(附完整源码)
- CVE-2018-4407 苹果设备远程溢出漏洞
- Objective-C使用位运算设计可复选的枚举
- linux系统备份和恢复
- 计算机黑屏策略,小黑w7系统诊断策略服务已被禁用的还原教程
- 各种好用的开源库。快点进来,包你喜欢~^_^
- ZooKeeper系列(3):znode说明和znode状态
- babel插件入门-AST
- (H2与HBase)面向行or面向列的存储模型?
- 3、plt.figure()和Axes类
- 最新最全的微信小程序入门学习教程,微信小程序零基础入门到精通
- 桑基图绘制的简易操作
- 淘宝美工设计需要掌握什么技能 ?小白如何快速学会美工设计?
- 分类模型到底如何选择
- AttributeError: module 'torch.nn' has no attribute 'LocalResponseNorm'问题的解决办法
- c# 自定义多个SplitContainer 支持点击放大缩小
- 基于JAVA汽车租赁平台的设计与实现计算机毕业设计源码+系统+mysql数据库+lw文档+部署