当前位置:网站首页>Todolist classic case ①
Todolist classic case ①
2022-07-01 07:19:00 【18 hate programming】
List of articles
Case introduction
As shown in the figure below :
There are a few small details :
When all events are checked , The following has been completed, and the previous box will also be checked automatically
Only after at least one event is selected , Will appear “ Clear completed tasks ” The button

When there are no to-do events in the list , The completed line will not be displayed as a whole

The added event appears at the top of the list
The case requires
Use the front end frame Vue Realization
And does not use the global event bus 、 Knowledge about message subscription and publication
case analysis
First of all, according to componentization, we must split this to-do list . Of course, there are many ways to disassemble , I recommend two :
- It's divided into three parts :

- Divided into four parts

Here I use the second method , We name each component :
- Red part components – headers.vue
- Green part components – tasks.vue
- Pink part components – task.vue
- Blue components – record.vue
Code implementation
App Components
<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: ' sleep ', completed: true}, {
id: 2, inform: ' having dinner ', completed: false}, {
id: 3, inform: ' Drink lots of water ', completed: true}, // Note here is the demonstration data , Delete in real time , Otherwise you may report an error . According to the code logic , If you delete one , Add another , Will appear // Two id by 3 The data of , Then the operation will be confused . // Be careful : there tasks Data can be transferred directly ] } }, 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) {
// Note that what we want to discuss here is the situation after pressing the button 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>
Be careful :
- Consider that several components may use tasks data , So we put it in the parent component of these components App in , This facilitates the transfer of data
- tasks There are several demonstration data . Delete in real time , Otherwise you may report an error . According to the code logic , If you delete one , Add another , There will be two id by 3 The data of , Then the operation will be confused .
- We use props To realize the function of transferring data from parent component to child component
- If the child component wants to pass data to the parent component , We first define a method in the parent component , Pass to subcomponent , Then let the sub component call
- Although it USES the data Function of , But here tasks It can also be used directly props Delivered
- Show the data that does not need to be modified directly props Just go ; If you want to change the data , Where the data is, the method is
headers Components
<template>
<input type="text" class="read" placeholder=" Press down Enter Add to do event " @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>
Be careful :
- After entering the to-do event , Press down enter After adding , The input box should be cleared
tasks Components
<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>
Be careful :
- Used v-for The tag of cannot be used as the root tag , So here I use div Another layer
task Components
<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)"> Delete </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>
When doing this part , The difficulty must be how to act on specific elements . How do you understand that ? That is, after we click the check box in front of an item , How can we accurately modify his data ? adopt id that will do , Because we put the callback method of click event in App In the component , So this is the process of transferring data from the child component to the parent component , We define the method in the parent component , And pass it to the sub components , Then the method is called by the sub component , Pass in data while calling , In this way, you can accurately pass id Operate to the corresponding data .
record Components
<template>
<div class="record" v-show="tasks.length != 0">
<!-- :checked="finish == tasks.length && tasks.length > 0 " This is to delete the blank list , Uncheck the -->
<input type="checkbox" :checked="getFinished() == tasks.length && tasks.length > 0 " ref="checkAll" @click="selectAll($refs.checkAll)">
Completed {
{getFinished()}}/ All {
{tasks.length}}
<!-- Show this data that doesn't need to be changed directly props Just go , If you want to change the data , Where the data is, the method is -->
<!-- v-show If your expression is a method , So this method is to bring () Of -->
<button class="delete" @click="deleteAllTasks" v-show="ifShow()"> Clear completed tasks </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>
Be careful :
- v-show If your expression is a method , So this method is to bring () Of
There is no need to ref To get DOM node , We can also use the click event object target Property to get the element directly , Let me introduce two commonly used vue Method to get the event object in :
Method ①:$event keyword ( It is applicable when the event callback function has foreign parameters )
Method ②: Write the callback function name directly ( It is applicable to the event callback function without external parameters )
Case summary
summary TodoList Case study
Componentized coding process :
(1). Split static components : Components should be split according to function points , Do not name with html Element conflict .
(2). Implement dynamic components : Consider where the data is stored , Data is a component in use , Some components are still in use :
1). A component is in use : Just put it on the component itself .
2). Some components are in use : On their common parent component ( Status up ).
(3). Implement interaction : Start with binding events .
props Apply to :
(1). Parent component ==> Child components signal communication
(2). Child components ==> Parent component signal communication ( Ask the parent to give the child a function first )
Use v-model Remember to :v-model Bound value cannot be props Transmitted value , because props It can't be modified !
props If the value of the object type is passed , When modifying properties in an object Vue No mistake. , But this is not recommended .
边栏推荐
- Those high-frequency written tests and interview questions in [Jianzhi offer & Niuke 101] - linked list
- redisson使用全解——redisson官方文档+注释(上篇)
- ctfshow-web352,353(SSRF)
- [programming compulsory training 3] find the longest consecutive number string in the string + the number that appears more than half of the times in the array
- Jax's deep learning and scientific computing
- Redisson utilise la solution complète - redisson Documents officiels + commentaires (Partie 1)
- Is it safe to buy funds on the brokerage account
- JAX的深度学习和科学计算
- 運維管理系統,人性化操作體驗
- Operation and maintenance management system, humanized operation experience
猜你喜欢

C# Newtonsoft.Json中JObject的使用

ctfshow-web354(SSRF)

【计网】(一) 集线器、网桥、交换机、路由器等概念

比赛即实战!中国软件杯发布全新产业创新赛项,校企可联合参赛

JAX的深度学习和科学计算

【LINGO】求七个城市最小连线图,使天然气管道价格最低

Product learning (II) - competitive product analysis

继妹变继母,儿子与自己断绝关系,世界首富马斯克,为何这么惨?

ctfshow-web351(SSRF)

The computer has a network, but all browser pages can't be opened. What's the matter?
随机推荐
Chinese explanation of common rclone subcommands
ctfshow-web351(SSRF)
【计网】(一) 集线器、网桥、交换机、路由器等概念
MySQL table partition creation method
开源了!文心大模型ERNIE-Tiny轻量化技术,又准又快,效果全开
Warm congratulations on the successful listing of five elements hehe liquor
Are there any practical skills for operation and maintenance management
1286_ Implementation analysis of task priority setting in FreeRTOS
【LINGO】求解二次规划
[programming compulsory training 3] find the longest consecutive number string in the string + the number that appears more than half of the times in the array
图像风格迁移 CycleGAN原理
未来互联网人才还稀缺吗?哪些技术方向热门?
Solution to the problem that objects in unity2021 scene view cannot be directly selected
Fix the problem that the AI video intelligent platform easycvr device video cannot be played
广发证券开户是安全可靠的么?怎么开广发证券账户
Webapck packaging principle -- Analysis of startup process
Vscode automatically formats code according to eslint specification
vscode 根据 ESLint 规范自动格式化代码
华为ModelArts训练Alexnet模型
ctfshow-web354(SSRF)


