总结ToDoList案例:

1.组件化编码流程:

(1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突.

(2).实现动态组件:考虑好数据的存放位置,数据是一个组件再用,还是一些组件在用.

a:一个组件在用,放在自身即可.

b:一些组件在用,放在他们共同的父组件上(状态提升).

(3).实现交互:从绑定事件开始.

2.props适用于:

(1).父组件 ===> 子组件 通信

(2).子组件 ===> 父组件 通信 (要求父组件先给子组件一个函数)

3.使用v-model时要注意:v-model绑定的值不能是props传过来的值,因为props是不可以修改的.

4.props传过来的若是对象类型的值,修改对象中的属性事,vue不会报错,但不推荐这样做.

我这些代码都是跟着老师敲的,其中已经运用到了组件自定义事件和全局事件总栈,有代码需要的小伙伴可以自行删除.

App.vue

//App.vue
<template><div id="root"><div class="todo-container"><div class="todo-wrap"><MyHeader @addTodo="addTodo"></MyHeader><MyList :todos="todos"></MyList><MyFooter:todos="todos"@checkAllTodo="checkAllTodo"@clearAllTodo="clearAllTodo"></MyFooter></div></div></div>
</template><script>
import MyHeader from "../src/components/MyHeader";
import MyList from "../src/components/MyList";
import MyFooter from "../src/components/MyFooter";export default {name: "App",components: {MyHeader,MyList,MyFooter,},data() {return {todos: JSON.parse(localStorage.getItem("todos")) || [],};},methods: {// 添加一个todoaddTodo(todoObj) {this.todos.unshift(todoObj);},// 勾选或取消勾选一个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;});},// 全选或取消全选checkAllTodo(done) {this.todos.forEach((todo) => {todo.done = done;});},// 清除所有已经完成的todoclearAllTodo() {this.todos = this.todos.filter((todo) => {return !todo.done;});},},watch: {todos: {deep: true,handler(value) {localStorage.setItem("todos", JSON.stringify(value));},},},mounted(){this.$bus.$on('checkTodo',this.checkTodo)this.$bus.$on('deleteTodo',this.deleteTodo)},beforeDestroy(){this.$bus.$off('checkTodo')this.$bus.$off('deleteTodo')}
};
</script><style>
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>

MyHeader.vue

//MyHeader.vue
<template><div class="todo-header"><inputtype="text"placeholder="请输入你的任务名称,按回车键确认"@keyup.enter="add"v-model="title"/></div>
</template><script>
import { nanoid } from 'nanoid'
export default {name: "MyHeader",data() {return {title:''};},methods: {add() {// 校验数据if(!this.title.trim()) return alert('输入不能为空')// 将用户的输入包装成一个对象const todoObj = { id: nanoid(), title: this.title, done: false };// 通知App组件去添加一个对象this.$emit('addTodo',todoObj);//清空输入this.title = '';},},
};
</script><style scoped>
.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>

MyList.vue

//MyList.vue
<template><ul class="todo-main"><MyItem v-for="todoObj in todos" :key="todoObj.id" :todo="todoObj" /></ul>
</template><script>
import MyItem from "./MyItem.vue";
export default {name: "MyList",components: { MyItem },// 声明接收App传过来的数据props:['todos']};
</script><style scoped>
.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>

MyItem.vue

//MyItem.vue
<template><li><label><inputtype="checkbox":checked="todo.done"@change="handleCheck(todo.id)"/><!-- 如下代码也能实现功能,但是不太推荐,因为有点违反原则,因为修改了props --><!-- <input type="checkbox" v-model="todo.done"/>  --><span>{{ todo.title }}</span></label><button class="btn btn-danger" @click="handleDelete(todo.id)">删除</button></li>
</template><script>
export default {name: "MyItem",//声明接收todo对象props: ["todo"],methods: {//勾选or取消勾选handleCheck(id) {// 通知App将对应的todo的done值取反// this.checkTodo(id);this.$bus.$emit('checkTodo', id);},// 删除handleDelete(id) {if (confirm("确定删除吗?")) {// this.deleteTodo(id);this.$bus.$emit('deleteTodo', id);}},},
};
</script><style scoped>
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: #ccc;
}
li:hover button {display: block;
}
</style>

MyFooter.vue

MyFooter.vue
<template><div class="todo-footer" v-if="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'],computed:{total(){return this.todos.length},// 第一种方法// doneTotal(){//   let i = 0 //   this.todos.forEach((todo) => {//     if(todo.done) i++//   })//   return i// }// 第二种方法doneTotal(){// const x = this.todos.reduce((pre,current)=>{//   console.log('@',pre,current)//   return pre + (current.done ? 1 : 0)// },0)// 简写return this.todos.reduce((pre,current)=> pre + (current.done ? 1 : 0),0)},isAll:{get(){return this.doneTotal === this.total && this.total > 0},set(value){this.$emit('checkAllTodo',value)}}},methods:{checkAll(e){this.checkAllTodo(e.target.checked)},clearAll(){this.$emit('clearAllTodo')}}
};
</script><style scoped>
.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>

main.js

//main.js
//引入vue
import Vue from 'vue'
//引入App
import App from './App.vue'
//关闭Vue的生产提示
Vue.config.productionTip = falsenew Vue({// 这里的"#app"的a为小写el:"#app",render: h => h(App),//安装全局事件总线beforeCreate(){Vue.prototype.$bus = this},
})

已经完成啦!可以实现增加,删除及统计功能.

ToDoList 案例完整 尚硅谷相关推荐

  1. 【Vue实践】尚硅谷张天禹Vue学习笔记(087-135)-20221212~20221218

    (任意组件通信)084-086_全局事件总线 全局事件总线SOP 086_TodoList案例_事件总线 src/mian.js: import Vue from 'vue' import App f ...

  2. 尚硅谷todolist案例

    vue todolist案例 1 拆分组件 一共拆分为4个组件 TodoHeader TodoItem TodoList TodoFooter item是list的子组件 2 组件化编码流程 实现静态 ...

  3. 尚硅谷-宋红康-JVM上中下篇完整笔记-JVM上篇_内存与垃圾回收篇

    前言 一.jvm及java体系结构 1. Java及JVM简介 TIOBE语言热度排行榜 https://www.tiobe.com/tiobe-index/ 世界上没有最好的编程语言,只有最适用于具 ...

  4. 尚硅谷Redis6基础教程-秒杀案例中库存遗留问题

    尚硅谷redis6基础教程中视频24-27的秒杀案例,使用Redis乐观锁解决了超卖问题,但是也产生了库存遗留问题.引入Lua脚本,解决了超卖和库存遗留.Lua脚本为什么解决了库存遗留问题???

  5. 【HBase学习笔记-尚硅谷-Java API shell命令 谷粒微博案例】

    HBase学习笔记 HBase 一.HBase简介 1.HBase介绍 2.HBase的逻辑结构和物理结构 3.数据模型 4.基本架构 二.快速入门 1.配置HBase 2.命令 三.API 1.获取 ...

  6. 尚硅谷大数据技术Spark教程-笔记09【SparkStreaming(概念、入门、DStream入门、案例实操、总结)】

    尚硅谷大数据技术-教程-学习路线-笔记汇总表[课程资料下载] 视频地址:尚硅谷大数据Spark教程从入门到精通_哔哩哔哩_bilibili 尚硅谷大数据技术Spark教程-笔记01[SparkCore ...

  7. Java web 2022跟学尚硅谷书城项目完整开源分享

    Java web 2022跟学尚硅谷书城项目完整开源分享 项目介绍 项目类图 sql建表和添加数据 界面展示 用户登录界面 用户注册界面 首页 添加购物车 我的购物车 我的订单 功能说明 项目介绍 跟 ...

  8. 【尚硅谷】Vue.js从入门到精通笔记

    目录 第1章:Vue核心 1-1.Vue简介 1-1-1.什么是Vue 1-1-2.Vue的特点 1-1-3.搭建Vue开发环境 1-1-4.创建Vue对象 1-2.模板语法 1-3.数据绑定 1-4 ...

  9. Vue笔记-尚硅谷-Alex

    Vue笔记 Vue简介 官网 英文官网: https://vuejs.org/ 中文官网: https://cn.vuejs.org/ 介绍与描述 动态构建用户界面的渐进式 JavaScript 框架 ...

最新文章

  1. HTTP_HOST 和 SERVER_NAME 的区别
  2. [转载]C#中各种计时器
  3. 大数据集群启停shell脚本:hadoop(hdfs、yarn)、hbase集群启停
  4. GIT项目管理工具(part2)--初始配置
  5. resin php extensions sockets,linux 有关笔记
  6. html图片分类插件,Quicksand-jQuery超酷图片分类插件
  7. [转载]如何用C#语言构造蜘蛛程序
  8. 今日恐慌与贪婪指数为78 贪婪程度有所缓解
  9. centos6.5-64安装zabbix2.4
  10. CMS:内容管理系统
  11. yum install安装时 提示“Another app is currently holding the yum lock; waiting for it to exit...”原因和解决
  12. 再传喜讯,鸿雁中标杭州地铁3号线配电工程
  13. html和js根据年份计算年龄,JS实现根据出生年月计算年龄
  14. php readystate,ajax+php打造进度条 readyState各状态
  15. 内网安全检测技术yyds!你还不会吗?
  16. (二)D3D9视频显示的流程与初始化
  17. vcs_dve+sverilog
  18. linux sli 提高效率,性能到底提升几倍?多卡SLI的效率测试
  19. 衢州,“最多跑一次”的先行者
  20. java坦克大战 实训报告_坦克大战系统《Java程序开发实训》综合实训报告.doc

热门文章

  1. 苹果刷机服务器验证失败,iPhone手机刷机报错最全总结 教你学会分析手机问题出在哪...
  2. oracle将表导入到表空间,关于ORALCE一个表空间的数据导入到另一个表空间的方法(原创)...
  3. MPA海洋捕食者算法学习笔记
  4. Java SE - 10 - 多线程
  5. 每天一篇论文 323/365 Designing Energy-Efficient Convolutional Neural Networks using Energy-Aware Pruning
  6. 带附件的邮件的发送方法
  7. Flink实时数据处理实践经验(Flink去重、维表关联、定时器、双流join)
  8. 华为路由交换由浅入深系列(二):静态路由、浮动路由、默认路由配置以及华为路由协议优先级总结
  9. MIPI通讯的初理解
  10. C printf() 详解之终极无惑