当前位置:网站首页>TodoList经典案例①
TodoList经典案例①
2022-07-01 07:17:00 【十八岁讨厌编程】
案例介绍
如下图所示:
有几个小细节:
当所有事件都被勾选之后,下面已完成前面的框也会自动勾选
只有在至少一个事件被选中之后,才会出现“清除已完成任务”的按钮

当列表中没有待办事件的时候,已完成的那一行整体都不会显示

添加的事件出现在列表的最上面
案例要求
使用前端框架Vue实现
且不使用全局事件总线、消息订阅与发布的有关知识
案例分析
首先根据组件化我们肯定是要对这个待办列表进行拆分的。当然这里有很多拆法,我推荐两种:
- 分成三个部分:

- 分成四个部分

在这里我使用第二种方式,我们将每一个组件命名:
- 红色部分组件 – headers.vue
- 绿色部分组件 – tasks.vue
- 粉色部分组件 – task.vue
- 蓝色部分组件 – record.vue
代码实现
App组件
<template>
<div id="app">
<Headers :addTasks="addTasks" :getLength="getLength"></Headers>
<Tasks :tasks="tasks" :updateTasks="updateTasks" :deleteTask="deleteTask"> </Tasks>
<Record :tasks="tasks" :getFinished="getFinished" :deleteAll="deleteAll" :selectAll="selectAll"></Record>
</div>
</template>
<script> import Headers from './components/headers' import Tasks from './components/tasks' import Record from './components/record' export default {
name: 'App', components: {
Headers, Tasks, Record }, data() {
return {
tasks: [ {
id: 1, inform: '睡觉', completed: true}, {
id: 2, inform: '吃饭', completed: false}, {
id: 3, inform: '喝水', completed: true}, //注意此处是示范数据,在实际时候删除,否则可能会报错。按照代码逻辑,如果你删除一个,再添加一个,就会出现 // 两个id为3的数据,那么操作会发生混乱。 //注意:这里的tasks是可以直接进行数据传递的 ] } }, methods: {
addTasks(task) {
this.tasks.unshift(task) console.log(this.tasks) }, getLength() {
return this.tasks.length }, updateTasks(id) {
for (let i = 0; i < this.tasks.length; i++) {
if (this.tasks[i].id === id) {
this.tasks[i].completed = !this.tasks[i].completed } } }, getFinished() {
let sum = 0 for (let i = 0; i < this.tasks.length; i++) {
if (this.tasks[i].completed == true) {
sum++ } } return sum }, deleteTask(id) {
this.tasks = this.tasks.filter(value => {
return value.id !== id }) }, deleteAll() {
this.tasks = this.tasks.filter(value => {
return value.completed == false }) }, selectAll(obj) {
//注意这里要讨论的是按下按钮之后的情况 if (obj.checked == true) {
for (let i = 0; i < this.tasks.length; i++) {
this.tasks[i].completed = true } } else {
for (let i = 0; i < this.tasks.length; i++) {
this.tasks[i].completed = false } } }, } } </script>
<style> #app {
width: 400px; text-align: center; border-width: 2px; border-color: #eaeaea; border-style: solid; border-radius: 10px; } </style>
注意点:
- 考虑到有几个组件可能会使用到tasks数据,所以我们把它放到这些组件的父组件App中,如此便于数据的传递
- tasks里面有几条示范数据。在实际时候删除,否则可能会报错。按照代码逻辑,如果你删除一个,再添加一个,就会出现两个id为3的数据,那么操作会发生混乱。
- 我们使用props来实现父组件向子组件传递数据的功能
- 如果子组件要向父组件传递数据,我们首先要在父组件中定义一个方法,传递给子组件,再让子组件调用即可
- 虽然使用的是data的函数式,但是这里的tasks也是可以直接使用props传递的
- 展示不需要修改的数据直接props就行;如果要改变数据,数据在哪里方法就在哪里
headers组件
<template>
<input type="text" class="read" placeholder="按下Enter添加待办事件" @keydown.enter="addTask" v-model="task">
</template>
<script> export default {
name: "MyHeader", props:['addTasks','getLength'], data(){
return {
task:'', } }, methods:{
addTask(){
this.addTasks( {
id:this.getLength()+1,inform:this.task,completed:false} ) this.task='' }, } } </script>
<style scoped> .read {
width:370px; margin-top: 20px; border: 2px solid #e3e2e2; border-radius: 10px; height: 25px; font-size: 20px; color: orange; } </style>
注意点:
- 在输入完待办事件,按下enter添加之后,输入框要清空
tasks组件
<template>
<div>
<ul id="form" v-for="task in tasks" :key="task.id">
<Task :task="task" :updateTasks="updateTasks" :deleteTask="deleteTask"></Task>
</ul>
</div>
</template>
<script> import Task from "@/components/task"; export default {
name: "MyTasks", props:['tasks','updateTasks','deleteTask'], components:{
Task } } </script>
<style scoped> #form {
list-style-type: none; padding: 0px; } </style>
注意:
- 使用了v-for的标签是不能当作根标签的,所以这里我使用div再包裹一层
task组件
<template>
<li class="tasks" >
<input type="checkbox" class="select" :checked="task.completed" @click="handleTask(task.id)">{
{task.inform}}<button class="delete" @click="deleteOne(task.id)">删除</button>
</li>
</template>
<script> export default {
name: "MyTask", props:['task','updateTasks','deleteTask'], methods:{
handleTask(id){
this.updateTasks(id) }, deleteOne(id){
this.deleteTask(id) } }, } </script>
<style scoped> li {
text-align: left; width: 370px; margin: 0 auto; border: 2px solid #e3e2e2; height: 30px; line-height: 30px; } li:hover {
background-color: #dcdcdc; visibility: visible; } li:hover .delete {
visibility: visible; } .delete {
height: 30px; color: white; background-color: red; border-radius: 5px; visibility: hidden; float: right; } </style>
在做这一部分的时候,难点肯定是怎么作用到具体的元素。怎么理解呢?就是说我们在点击了某一项前面的勾选框之后,我们怎么精确的修改到他的数据?通过id即可,因为我们将点击事件的回调方法放在了App组件中,所以这是一个子组件向父组件传递数据的过程,我们在父组件中定义好方法,并传递给子组件,再由子组件来调用这个方法,在调用的同时传入数据,如此就可以精准的通过id操作到对应的数据。
record组件
<template>
<div class="record" v-show="tasks.length != 0">
<!-- :checked="finish == tasks.length && tasks.length > 0 " 此处是为了列表删除为空之后,取消勾选-->
<input type="checkbox" :checked="getFinished() == tasks.length && tasks.length > 0 " ref="checkAll" @click="selectAll($refs.checkAll)">
已完成{
{getFinished()}}/全部{
{tasks.length}}
<!-- 展示这种不需要改变的数据直接props就行,如果要改变数据,数据在哪里方法就在哪里-->
<!-- v-show里面如果你这个表达式是一个方法,那么这个方法是要带()的-->
<button class="delete" @click="deleteAllTasks" v-show="ifShow()">清除已完成任务</button>
</div>
</template>
<script> export default {
name: "MyRecord", props:['getFinished','deleteAll','selectAll','tasks'], methods:{
deleteAllTasks(){
this.deleteAll() this.$refs.fuyuan.checked = false }, ifShow(){
for (let i = 0; i < this.tasks.length; i++) {
if(this.tasks[i].completed === true) return true } return false } } } </script>
<style scoped> .record {
width:370px; margin:0 auto; text-align: left; height: 35px; } .delete {
height: 30px; color: white; background-color: red; border-radius: 5px; /*visibility: hidden;*/ float: right; } </style>
注意:
- v-show里面如果你这个表达式是一个方法,那么这个方法是要带()的
此处可以不用ref来获取DOM节点,我们也可以使用点击事件对象的target属性来直接获得到这个元素,下面我介绍两种常用的在vue中获取事件对象的方法:
方法①:$event关键字(适用于事件回调函数有外来参数的时候)
方法②:直接写回调函数名(适用于事件回调函数没有外来参数的时候)
案例总结
总结TodoList案例
组件化编码流程:
(1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。
(2).实现动态组件:考虑好数据的存放位置,数据是一个组件在用,还是一些组件在用:
1).一个组件在用:放在组件自身即可。
2). 一些组件在用:放在他们共同的父组件上(状态提升)。
(3).实现交互:从绑定事件开始。
props适用于:
(1).父组件 ==> 子组件 通信
(2).子组件 ==> 父组件 通信(要求父先给子一个函数)
使用v-model时要切记:v-model绑定的值不能是props传过来的值,因为props是不可以修改的!
props传过来的若是对象类型的值,修改对象中的属性时Vue不会报错,但不推荐这样做。
边栏推荐
- 为什么这么多人转行产品经理?产品经理发展前景如何?
- Jax's deep learning and scientific computing
- go-etcd
- 运维管理有什么实用的技巧吗
- 电脑有网络,但所有浏览器网页都打不开,是怎么回事?
- 1286_FreeRTOS的任务优先级设置实现分析
- 熱烈祝賀五行和合酒成功掛牌
- ctfshow-web355,356(SSRF)
- [recommendation technology] matlab simulation of network information recommendation technology based on collaborative filtering
- How to draw a product architecture diagram?
猜你喜欢

如何进入互联网行业,成为产品经理?没有项目经验如何转行当上产品经理?
![[programming training] delete public characters (hash mapping) + team competition (greedy)](/img/cd/63eb9da1e8956df0763797f079b67f.png)
[programming training] delete public characters (hash mapping) + team competition (greedy)

Apple账号密码自动填充
![[Electrical dielectric number] electrical dielectric number and calculation considering HVDC and facts components](/img/7c/2b1d4797f367cced51f36e8a1bb199.png)
[Electrical dielectric number] electrical dielectric number and calculation considering HVDC and facts components

热烈祝贺五行和合酒成功挂牌

Product learning (III) - demand list

图像风格迁移 CycleGAN原理

Will Internet talents be scarce in the future? Which technology directions are popular?

atguigu----脚手架--02-使用脚手架(2)

How to permanently configure local opencv4.5.5 for vs2019
随机推荐
weback5基础配置详解
JAX的深度学习和科学计算
【推荐系统】美团外卖推荐场景的深度位置交互网络DPIN的突破与畅想
Code practice - build your own diffusion models / score based generic models from scratch
Fix the problem that the AI video intelligent platform easycvr device video cannot be played
Vscode automatically formats code according to eslint specification
STM32F1与STM32CubeIDE编程实例-NEC协议红外接收与解码
Servlet 和 JSP 中的分页
MySQL and redis consistency solution
Is it reliable to open an account on the compass with your mobile phone? Is there any potential safety hazard
Reply and explanation on issues related to "online training of network security education in 2022"
Cadence OrCAD Capture “网络名”相同,但是未连接或连接错误的解放方案之nodename的用法
C# Newtonsoft. Use of job in JSON
How to draw a product architecture diagram?
C# Newtonsoft.Json中JObject的使用
开源了!文心大模型ERNIE-Tiny轻量化技术,又准又快,效果全开
Introduction to spark (one article is enough)
ctfshow-web354(SSRF)
Are there any practical skills for operation and maintenance management
Detailed explanation of weback5 basic configuration


