<template> <div id="root"> <div class="todo-container"> <div class="todo-wrap"> <MyHeader @addTodo="addTodo"></MyHeader> <MyList :todos="todos"></MyList> <MyFooter :todos="todos" @checkAllTodo="checkAllTodo" @cleatAllTodo="cleatAllTodo"></MyFooter> </div> </div> </div> </template> <script> import pubsub from 'pubsub-js' import MyHeader from "./components/MyHeader.vue"; import MyList from "./components/MyList.vue"; import MyFooter from "./components/MyFooter.vue"; export default { name: "App", components: { MyHeader, MyList, MyFooter }, data() { return { todos: JSON.parse(localStorage.getItem('todos')) || [] }; }, methods:{ //添加一个todo addTodo(todoObj){ // console.log('我是App组件,我收到了数据:',todoObj) this.todos.unshift(todoObj) }, //勾选或取消勾选一个todo checkTodo(id){ this.todos.forEach((todo) => { if(todo.id === id) todo.done = !todo.done }) }, //更新一个todo updateTodo(id,title){ this.todos.forEach((todo) => { if(todo.id === id) todo.title = title }) }, //删除一个todo deleteTodo(_,id){ //使用了消息订阅与发布,当deleteTodo作为消息的回调使用时,会接收到两个参数, //第一个参数是msgName,由于本例用不上,所以使用下划线_,表示占位 // const todos = this.todos.filter((todo) => { // return todo.id !== id // }) //简化写法 this.todos = this.todos.filter(todo => todo.id !== id) }, //全选或取消全选 checkAllTodo(done){ this.todos.forEach((todo) => { todo.done = done }) }, //清除已经完成的todo cleatAllTodo(){ this.todos = this.todos.filter((todo) => { return !todo.done }) } }, // 实现本地存储 watch:{ todos:{ deep:true, handler(value){ localStorage.setItem('todos',JSON.stringify(value)) } } }, mounted(){ this.$bus.$on('checkTodo',this.checkTodo) // this.$bus.$on('deleteTodo',this.deleteTodo) this.pubId = pubsub.subscribe('deleteTodo',this.deleteTodo) this.$bus.$on('updateTodo',this.updateTodo) }, beforeDestroy(){ this.$bus.$off('checkTodo') // this.$bus.$off('deleteTodo') pubsub.unsubscribe(this.pubId) this.$bus.$off('updateTodo') } }; </script> <style> /*base*/ body { background: #fff; } .btn { display: inline-block; padding: 4px 12px; margin-bottom: 0; font-size: 14px; line-height: 20px; text-align: center; vertical-align: middle; cursor: pointer; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); border-radius: 4px; } .btn-danger { color: #fff; background-color: #da4f49; border: 1px solid #bd362f; } .btn-edit { color: #fff; background-color: skyblue; border: 1px solid rgb(108, 201, 238); margin-right: 5px; } .btn-danger:hover { color: #fff; background-color: #bd362f; } .btn:focus { outline: none; } .todo-container { width: 600px; margin: 0 auto; } .todo-container .todo-wrap { padding: 10px; border: 1px solid #ddd; border-radius: 5px; } </style>