1 <Template> 2 <div class = "TODO-header"> 3 < the INPUT 4 of the type = "text" 5 placeholder = "Please enter today's task list, press Enter" 6 v-Model = "title" 7 keyup.enter = @ "the addItem" . 8 /> . 9 </ div> 10 </ Template> . 11 12 is <Script> 13 is Export default { 14 name: "Header" , 15 data(){ 16 return { 17 title: '' 18 is } . 19 }, 20 is Methods: { 21 is the addItem () { 22 is // 1. determines whether the air 23 is const title = the this .title.trim (); 24 IF (! title) { 25 Alert ( ' input task can not be empty '! ); 26 is return ; 27 } 28 // 2. todo generate a target 29 the let {title = todo, Finished: to false }; 30 // 3. insertion method call parent element 31 // this.addTodo(todo); 32 this.$emit('addTodo', todo); 33 34 // 4. 清空输入框 35 this.title = ''; 36 } 37 } 38 } 39 </script> 40 41 <style scoped> 42 .todo-header input { 43 width: 560px; 44 height: 28px; 45 font-size: 14px; 46 border: 1px solid #ccc; 47 border-radius: 4px; 48 padding: 4px 7px; 49 outline: none; 50 } 51 52 .todo-header input:focus { 53 outline: none; 54 border-color: rgba(255, 0, 0, 0.8); 55 box-shadow: inset 0 1px 1px rgba(255, 0, 0, 0.075), 0 0 8px rgba(255, 0, 0, 0.6); 56 } 57 </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">Clear completed tasks </ the Button> 12 </ div> 11 </ Footer> 10 </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 is the this .selectedAllTodo (value); 42 is } 43 is } 44 is }, 45 Components: { 46 is Header, 47 List, 48 Footer 49 }, 50 Mounted () { 51 is // binding custom event (addTodo ) monitor 52 is the this $ $ refs.header ON ( 'addTodo',.. the this .addTodo); 53 is // subscription message (delTodo) 54 is PubSub.subscribe ( 'delTodo', (MSG, token) =>{ 55 // the console.log (MSG, token); 56 is the this .delTodo (token); 57 is }); 58 }, 59 Methods: { 60 // inserts a row 61 is addTodo (TODO) { 62 is the this .todos.unshift (TODO); 63 }, 64- // index according to delete a record 65 delTodo (index) { 66 the this .todos.splice (index, 1 ); 67 }, 68 // whether to select all tasks 69 selectedAllTodo (isCheck) { 70 this .todos.forEach (all => { 71 todo.finished = isCheck 72 }) 73 }, 74 delFinishedTodos () { 75 this .all = this .todos.filter (all => todo.finished) 76 } 77 }, 78 watch: { 79 // 深度监视 80 all: { 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>