当前位置:网站首页>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不会报错,但不推荐这样做。
边栏推荐
- [image processing] image histogram equalization system with GUI interface
- Is the account opening of GF Securities safe and reliable? How to open GF Securities Account
- ctfshow-web352,353(SSRF)
- MySQL table partition creation method
- Will Internet talents be scarce in the future? Which technology directions are popular?
- kdtree(kd树)笔记
- Fix the problem that the AI video intelligent platform easycvr device video cannot be played
- Rclone access web interface
- How the esp32 deep sleep current is lower than 10uA
- 为什么这么多人转行产品经理?产品经理发展前景如何?
猜你喜欢

C# 读写自定义的Config文件
![Those high-frequency written tests and interview questions in [Jianzhi offer & Niuke 101] - linked list](/img/9a/44976b5df5567a7aff315e63569f6a.png)
Those high-frequency written tests and interview questions in [Jianzhi offer & Niuke 101] - linked list

Why did grayscale fall from the altar?

How to draw a product architecture diagram?

The programmer of Beipiao posted a post for help late at night: I am lonely when my girlfriend is gone
![[programming training] delete public characters (hash mapping) + team competition (greedy)](/img/cd/63eb9da1e8956df0763797f079b67f.png)
[programming training] delete public characters (hash mapping) + team competition (greedy)

iNFTnews | 从《雪崩》到百度“希壤”,元宇宙30年的16件大事

Code practice - build your own diffusion models / score based generic models from scratch

How to permanently configure local opencv4.5.5 for vs2019

华为ModelArts训练Alexnet模型
随机推荐
Stepsister becomes stepmother, son breaks off relationship with himself, and musk, the world's richest man, why is it so miserable?
STM32F1与STM32CubeIDE编程实例-NEC协议红外接收与解码
ctfshow-web355,356(SSRF)
MySQL and redis consistency solution
Fix the problem that the AI video intelligent platform easycvr device video cannot be played
Paging in servlets and JSPS
Open source! Wenxin large model Ernie tiny lightweight technology, accurate and fast, full effect
Programming examples of stm32f1 and stm32subeide infrared receiving and decoding of NEC protocol
[programming training] delete public characters (hash mapping) + team competition (greedy)
Unity2021-Scene视图中物体无法直接选中的解决办法
【深圳IO】精确食品称(汇编语言的一些理解)
Operation and maintenance management system, humanized operation experience
未来互联网人才还稀缺吗?哪些技术方向热门?
【编程强训3】字符串中找出连续最长的数字串+数组中出现次数超过一半的数字
Webapck packaging principle -- Analysis of startup process
Microsoft announces open source (Godel) language model chat robot
MySQL table partition creation method
运维管理系统,人性化操作体验
[network planning] (I) hub, bridge, switch, router and other concepts
比赛即实战!中国软件杯发布全新产业创新赛项,校企可联合参赛


