黑马的课程案例:小黑记事本组件版
拆分基础组件、渲染待办功能、添加任务、删除任务、 底部合计和清空功能、持久化存储
这是一些代码的注释和解释
这是完整代码,可以直接复制使用
App.vue
<template>
<!-- 主体区域 -->
<section id="app">
<!-- 注册事件、监听子组件 -->
<TodoHeader @add="handleAdd"></TodoHeader>
<TodoMain :list="list" @del="handelDel"></TodoMain>
<TodoFooter :list="list" @clear="clear"></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: '看电影' },
{ id: 3, name: '逛街' },
],
}
},
components: {
TodoHeader,
TodoMain,
TodoFooter,
},
//6.持久化存储
watch: {
list: {
deep: true,
handler(newVal) {
localStorage.setItem('list', JSON.stringify(newVal))
},
},
},
methods: {
//添加---用时间戳添加
handleAdd(todoName) {
// console.log(todoName)
this.list.unshift({
id: +new Date(),
name: todoName,
})
},
//删除---过滤id
handelDel(id) {
// console.log(id);
this.list = this.list.filter((item) => item.id !== id)
},
//清空---让数组为空
clear() {
this.list = []
},
},
}
</script>
<style>
</style>
TodoHeader.vue
<template>
<!-- 输入框 -->
<header class="header">
<h1>小黑记事本</h1>
<input placeholder="请输入任务" class="new-todo"
v-model="todoName" @keyup.enter="handleAdd"/>
<!-- v-model获取输入框的值-->
<button class="add" @click="handleAdd">添加任务</button>
<!-- 给按钮注册点击事件-->
</header>
</template>
<script>
export default {
data(){
return {
todoName:'' //由v-model绑定输入获取,默认为空
}
},
methods:{
//添加
handleAdd(){
// console.log(this.todoName) //打印得到的todoName
this.$emit('add',this.todoName) //传递添加事件
this.todoName = '' //添加完成之后清空输入框
}
}
}
</script>
<style>
</style>
TodoMain.vue
<template>
<!-- 列表区域 -->
<section class="main">
<ul class="todo-list">
<!-- v-for渲染数据,:key必写 -->
<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 class="destroy" @click="handleDel(item.id)"></button>
</div>
</li>
</ul>
</section>
</template>
<script>
export default {
props: {
list: {
type: Array,
},
},
methods: {
handleDel(id) {
this.$emit('del', id) //传递删除参数id
},
},
}
</script>
<style>
</style>
TodoFooter.vue
<template>
<!-- 统计和清空 -->
<footer class="footer">
<!-- 统计 -->
<span class="todo-count"
>合 计:<strong> {{ list.length }} </strong></span
>
<!-- 注册清空事件 -->
<button class="clear-completed" @click="clear">清空任务</button>
</footer>
</template>
<script>
export default {
props: {
list: {
type: Array,
},
},
methods:{
clear(){
this.$emit('clear') //传递清空请求
}
}
}
</script>