素材领取:点击我领取素材
提取码:1024
我们的需求如下:
1.拆分基础组件
2.渲染待办任务
3.添加任务
4.删除任务
5.底部合计 和 清空功能
6.持久化存储
分析:
渲染功能:
1.提供数据: 提供在公共的父组件 App.vue
2.通过父传子,将数据传递给TodoMain
3.利用 v-for渲染
添加功能:
1.手机表单数据 v-model
2.监听事件(回车+点击都要添加)
3.子传父,讲任务名称传递给父组件 App.vue
4.进行添加 unshift(自己的数据自己负责)
5.清空文本框输入的内容
6.对输入的空数据 进行判断
删除功能
1.监听事件(监听删除的点击) 携带id
2.子传父,讲删除的id传递给父组件的App.vue
3.进行删除filter(自己的数据 自己负责)
底部合计:父传子 传list 渲染
清空功能:子传父 通知父组件 → 父组件进行更新
持久化存储:watch深度监视list的变化 -> 往本地存储 ->进入页面优先读取本地数据
父组件代码:
<template>
<section id="app">
<TodoHeader @add="handlerAdd">TodoHeader>
<TodoMain :list="list" @handlerDel="del">TodoMain>
<TodoFooter @clear="handlerClear" :list="list">TodoFooter>
section>
template>
<script>
import TodoHeader from "./components/TodoHeader.vue"
import TodoMain from "./components/TodoMain.vue"
import TodoFooter from "./components/TodoFooter.vue"
export default {
data() {
return {
// 准备一个数组存放数据 持久保存到本地
list: JSON.parse(localStorage.getItem("list")) || [
{ id: 1, name: "打篮球" },
{ id: 2, name: "踢足球" }
]
}
},
methods: {
handlerAdd(values) {
// 我们使用unshift()方法向数组的最前面添加数据
this.list.unshift({
// 使用时间戳作为id值
id: +new Date(),
name: values
})
},
del(id) {
// 使用filter去过滤数组完成删除
this.list = this.list.filter(item => item.id !== id)
},
handlerClear() {
this.list = []
}
},
watch: {
list: {
deep: true,
handler(newValue) {
localStorage.setItem("list", JSON.stringify(newValue))
}
}
},
components: {
TodoHeader,
TodoMain,
TodoFooter
}
}
script>
子组件TodoHeader代码:
<template>
<header class="header">
<h1>小黑记事本h1>
<input @keyup.enter="handlerAdd" v-model="msg" placeholder="请输入任务" class="new-todo" />
<button @click="handlerAdd" class="add">添加任务button>
header>
template>
<script>
export default {
data() {
return {
msg: ""
};
},
methods: {
handlerAdd() {
// 当msg为空时 我们需要返回
if (this.msg.trim() == "") {
alert("请输入值")
return
}
// 子传父 使用this.$emit()
this.$emit('add', this.msg);
// 添加完之后 我们需要把表单的值赋为空
this.msg = ""
}
},
};
script>
子组件TodoMain代码:
<template>
<section class="main">
<ul class="todo-list">
<li class="todo" v-for="(item, index) in list" :key="item.id">
<div class="view">
<span class="index">{{ index + 1 }}.span> <label>{{ item.name }}label>
<button @click="del(item.id)" class="destroy">button>
div>
li>
ul>
section>
template>
<script>
export default {
// 我们使用props
props: {
list: Array
},
methods: {
del(id) {
// 子传父
this.$emit('handlerDel', id);
}
},
};
script>
子组件TodoFooter代码:
<template>
<footer class="footer">
<span class="todo-count">合 计:<strong> {{ list.length }} strong>span>
<button @click="clear" class="clear-completed">
清空任务
button>
footer>
template>
<script>
export default {
// 我们把list通过父传子的方法传入
props: {
list: Array
},
methods: {
clear() {
// 子传父
this.$emit('clear');
}
},
};
script>
感谢大家的阅读,如有不对的地方,可以向我提出,感谢大家!