💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨
案例效果图:
咱们可以把记事本原有的结构拆成三部分内容:头部(TodoHeader)、列表(TodoMain)、底部(TodoFooter)
列表渲染
思路分析:
-
提供数据:提供在公共的父组件 App.vue
-
通过父传子,将数据传递给TodoMain
-
利用v-for进行渲染
添加功能
思路分析:
-
收集表单数据 v-model
-
监听时间 (回车+点击 都要进行添加)
-
子传父,将任务名称传递给父组件App.vue
-
父组件接受到数据后 进行添加 unshift(自己的数据自己负责)
删除功能
-
监听时间(监听删除的点击)携带id
-
子传父,将删除的id传递给父组件App.vue
-
进行删除 filter (自己的数据自己负责)
底部功能及持久化存储
-
底部合计:父组件传递list到底部组件 —>展示合计
-
清空功能:监听事件 —> 子组件通知父组件 —>父组件清空
-
持久化存储:watch监听数据变化,持久化到本地
源码分享
App.vue
<template><!-- 主体区域 --><section id="app"><TodoHeader @add="handleAdd"></TodoHeader><TodoMain @del="handleDel" :list="list"></TodoMain><TodoFooter @clear="handleClear" :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: "踢足球" },{ id: 3, name: "打棒球" },],};},methods: {handleAdd(todoName) {this.list.unshift({id: +new Date(),name: todoName,});},handleDel(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: {TodoHeader,TodoMain,TodoFooter,},
};
</script><style>
</style>
TodoHeader.vue
<template><!-- 输入框 --><header class="header"><h1>记事本</h1><input@keyup.enter="handleAdd"v-model="todoName"placeholder="请输入任务"class="new-todo"/><button @click="handleAdd" class="add">添加任务</button></header>
</template><script>
export default {data() {return {todoName: "",};},methods: {handleAdd() {if (this.todoName.trim() === "") {alert("任务名称不能为空");return;}this.$emit("add", this.todoName);this.todoName = "";},},
};
</script><style>
</style>
TodoMain.vue
<template><!-- 列表区域 --><section class="main"><ul class="todo-list"><li v-for="(item, index) in list" :key="item.id" class="todo"><div class="view"><span class="index">{{ index + 1 }}.</span><label>{{ item.name }}</label><button @click="handleDel(item.id)" class="destroy"></button></div></li></ul></section>
</template><script>
export default {props: {list: Array,},methods: {handleDel(id) {this.$emit("del", id);},},
};
</script><style>
</style>
TodoFooter.vue
<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 {props: {list: Array,},methods: {clear() {this.$emit("clear");},},
};
</script><style>
</style>
❤️❤️❤️小郑是普通学生水平,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄
💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏下吧,非常感谢!👍 👍 👍