1 <template> 2 <div class="todo-footer"> 3 <label> 4 <slot name="isCheck"></slot> 5 </label> 6 <span> 7 <slot name="finish"></slot> 8 </span> 9 <slot name="delete"></slot> 10 </div> 11 </template> 12 13 <script> 14 export default { 15 name: "Footer", 16 } 17 </script> 18 19 <style scoped> 20 .todo-footer { 21 height: 40px; 22 line-height: 40px; 23 padding-left: 6px; 24 margin-top: 5px; 25 } 26 27 .todo-footer label { 28 display: inline-block; 29 margin-right: 20px; 30 cursor: pointer; 31 } 32 33 .todo-footer label input { 34 position: relative; 35 top: -1px; 36 vertical-align: middle; 37 } 38 39 .todo-footer button { 40 float: right; 41 margin-top: 5px; 42 } 43 </style>
1 <template> 2 <div class="todo-container"> 3 <div class="todo-wrap"> 4 <Header ref="header"/> 5 <List :todos="todos" :delTodo="delTodo"/> 6 <Footer> 7 <input slot="isCheck" type="checkbox" v-model="isCheck"/> 8 <span slot="finish">已完成{{finishedCount}}件 / 总计{{todos.length}}件</span> 9 <button slot="delete" class="btn btn-warning" @click="delFinishedTodos">清除已完成任务</button> 10 </Footer> 11 </div> 12 </div> 13 </template> 14 15 <script> 16 // 引入组件 17 import Header from './components/Header' 18 import List from './components/List' 19 import Footer from './components/Footer' 20 21 // 引入工具类 22 import localStorageUtil from './utils/localStorageUtil' 23 import PubSub from 'pubsub-js' 24 25 export default { 26 name: 'app', 27 data() { 28 return { 29 todos: localStorageUtil.readTodos() 30 } 31 }, 32 computed: { 33 finishedCount() { 34 return this.todos.reduce((total, todo) => total + (todo.finished ? 1 : 0), 0); 35 }, 36 isCheck: { 37 get() { 38 return this.finishedCount === this.todos.length && this.todos.length > 0 39 }, 40 set(value) { 41 this.selectedAllTodo(value); 42 } 43 } 44 }, 45 components: { 46 Header, 47 List, 48 Footer 49 }, 50 mounted(){ 51 // 绑定自定义事件(addTodo)监听 52 this.$refs.header.$on('addTodo', this.addTodo); 53 // 订阅消息(delTodo) 54 PubSub.subscribe('delTodo', (msg, token)=>{ 55 // console.log(msg, token); msg=delTodo token 参数 56 this.delTodo(token); 57 }); 58 }, 59 methods:{ 60 // 插入一条数据 61 addTodo(todo){ 62 this.todos.unshift(todo); 63 }, 64 // 根据索引删除一条记录 65 delTodo(index){ 66 this.todos.splice(index, 1); 67 }, 68 // 是否选中所有的任务 69 selectedAllTodo(isCheck){ 70 this.todos.forEach(todo => { 71 todo.finished = isCheck 72 }) 73 }, 74 delFinishedTodos(){ 75 this.todos = this.todos.filter(todo=> !todo.finished) 76 } 77 }, 78 watch: { 79 // 深度监视 80 todos: { 81 handler: localStorageUtil.saveTodos, 82 deep: true, // 深度监视 83 // immediate: true 84 } 85 } 86 } 87 </script> 88 89 <style> 90 .todo-container { 91 width: 600px; 92 margin: 0 auto; 93 } 94 95 .todo-container .todo-wrap { 96 padding: 10px; 97 border: 1px solid #ddd; 98 border-radius: 5px; 99 } 100 </style>