核心步骤:
1. 拆分基础组件
新建组件 -> 拆分存放结构 -> 导入注册使用
2. 渲染待办任务
提供数据(公共父组件) -> 父传子传递 list -> v-for 渲染
3. 添加任务
收集数据 v-model -> 监听事件 -> 子传父传递任务 -> 父组件 unshift
4. 删除任务
监听删除携带 id -> 子传父传递 id -> 父组件 filter删除
5. 底部合计 和 清空功能
底部合计: 父传子传递 list -> 合计展示
清空功能: 监听点击 -> 子传父通知父组件 -> 父组件清空
6. 持久化存储: watch监视数据变化,持久化到本地
代码示例:
1. XxHeader.vue : 子传父,将输入框内容传递给父组件,父组件进行添加
<template>
<!-- 输入框 -->
<header>
<h1>记事本</h1>
<!-- 回车和点击都监听 -->
<input
@keyup.enter="handleAdd"
placeholder="请输入任务" v-model="doName">
<button @click="handleAdd">添加任务</button>
</header>
</template>
<script>
export default {
data() {
return {
doName: ""
}
},
methods:{
handleAdd(){
// console.log(this.doName)
if (this.doName.trim() ===''){
alert("任务名称不能为空")
return
}
this.$emit('add',this.doName)
this.doName=""
}
}
}
</script>
2. XxMain.vue: 父传子,渲染数据; 点击删除:子传父id,父组件进行过滤
<template>
<!-- 列表区域 -->
<section>
<ul>
<li v-for="(item,index) in list" :key="item.id">
<div >
<span>{{ index + 1 }}<label>{{ item.name }}</label></span>
<button @click="handleDel(item.id)">X</button>
</div>
</li>
</ul>
</section>
</template>
<script>
export default{
props:{
list:Array
},
methods:{
handleDel(id){
// console.log(id)
this.$emit('del',id)
}
}
}
</script>
3. XxFooter.vue: 父传子,统计长度; 点击清空,子传父,父组件清空数据
<template>
<!-- 统计和清空 -->
<footer>
<!-- 统计 -->
<span>合 计:<strong>{{ list.length }}</strong></span>
<!-- 清空 -->
<button @click="clear">
清空任务
</button>
</footer>
</template>
<script>
export default{
props:{
list:Array
},
methods:{
clear(){
this.$emit('clear')
}
}
}
</script>
4. App.vue
<template>
<div id="app">
<XxHeader @add="handleAdd"></XxHeader>
<XxMain :list="list" @del="handleDel"></XxMain>
<XxFooter :list="list" @clear="handleClear"></XxFooter>
</div>
</template>
<script>
import XxHeader from './components/XxHeader.vue'
import XxMain from './components/XxMain.vue'
import XxFooter from './components/XxFooter.vue'
// 渲染功能:
//1. 提供数据 -> 提供在公共组件 App.vue
//2. 通过父传子,将数据传递给 XxMain
//3. 利用 v-for 渲染
// 添加功能:
//1. 收集表单数据 -> v-model
//2. 监听事件 (回车 + 点击 都要进行监听)
//3. 子传父,将任务名称传递给父组件App.vue
//4. 父组件进行添加 unshift (自己的数据自己负责)
// 删除功能:
//1. 监听事件(监听删除的点击) 携带id
//2. 子传父,将删除的id传递给父组件App.vue
//3. 进行删除 filter (自己的数据自己负责)
// 底部合计: 父传子传list -> 渲染
// 清空功能: 子传父 通知到父组件 -> 父组件进行清空操作
// 持久化存储: watch深度监视list的变化 -> 往本地存储 -> 一进入页面优先读取本地
export default {
data() {
return {
// 先从本地获取,没有的话取默认值
list:JSON.parse(localStorage.getItem("list")) || [
{ id: 1, name: "唱" },
{ id: 2, name: "跳" },
{ id: 3, name: "rap" },
]
}
},
methods: {
handleAdd(doName) {
// console.log(doName)
this.list.unshift({
id: +new Date(),
name: doName
})
},
handleDel(id) {
// console.log("接收到子组件传递的id",id)
this.list = this.list.filter(item => item.id !== id)
},
handleClear() {
this.list = []
}
},
watch: {
list:{
deep:true,
handler(newValue){
//存储到本地
localStorage.setItem('list',JSON.stringify(newValue))
}
}
},
components: {
XxHeader,
XxMain,
XxFooter
}
}
</script>
<style></style>