1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 8 <title>VueTodoList</title> 9 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 10 <link href="css/style.css" rel="stylesheet" /> 11 <link href="css/animate.css" rel="stylesheet" /> 12 </head> 13 14 <body> 15 <div id="app"> 16 <header> 17 <section> 18 <form action="javascript:;"> 19 <label for="title">ToDoList</label> 20 <!-- 绑定回车事件 --> 21 <input type="text" id="title" name="title" placeholder="添加ToDo" autocomplete="off" required 22 v-model="addDoingThings" @keydown.enter="addDoingThingsList" /> 23 </form> 24 </section> 25 </header> 26 <section> 27 <h2>正在进行 <span id="todocount">0</span></h2> 28 <div id="todolist" class="demo-box"> 29 <transition-group name="slide" enter-active-class="animated bounceInLeft" 30 leave-active-class="animated bounceOutRight"> 31 <span class="doingItem" v-for="(item, index) in doingList" :key="‘item‘+index"> 32 <input type="checkbox" @click.prevent="checkDoneThings(item.id)"> 33 <span>{{item.content}}</span> 34 <a href="javascript:;" class="delBtn" @click.prevent="delThings(item.id)">-</a> 35 </span> 36 </transition-group> 37 </div> 38 <h2>已经完成 <span id="donecount">0</span></h2> 39 <div id="donelist"> 40 <transition-group name="slide" enter-active-class="animated bounceInLeft" 41 leave-active-class="animated bounceOutRight"> 42 <span class="doneItem" v-for="(item, index) in doneList" :key="‘item‘+index"> 43 <input type="checkbox" checked @click.prevent="checkDoneThings(item.id)"> 44 <span>{{item.content}}</span> 45 <a href="javascript:;" class="delBtn" @click.prevent="delThings(item.id)">-</a> 46 </span> 47 </transition-group> 48 </div> 49 </section> 50 <footer> 51 Copyright © 2020 <a href="https://www.cnblogs.com/rchi/">股股清流@博客园</a> 52 </footer> 53 </div> 54 <script> 55 var app = new Vue({ 56 el: ‘#app‘, 57 data: { 58 todoList: [], 59 addDoingThings: "" 60 }, 61 computed: { 62 //通过过滤未做好事情列表和已做好事件列表 63 //正在做的事件 64 doingList: function () { 65 let arr = this.todoList.filter(function (item, index) { 66 return !item.isDone 67 }) 68 return arr; 69 }, 70 //已做好的事件 71 doneList: function () { 72 let arr = this.todoList.filter(function (item, index) { 73 return item.isDone 74 }) 75 return arr; 76 } 77 }, 78 mounted() { 79 //页面初始化完毕,从本地存储中拿到todoList替换本地todoList 80 this.todoList = localStorage.todoList ? JSON.parse(localStorage.todoList) : []; 81 }, 82 methods: { 83 //添加待做事情列表,id:要做的事情的序号,content:要做的事情,idDone:是否做好,默认是未做好 84 addDoingThingsList: function () { 85 if (this.addDoingThings == "") return 86 this.todoList.push({ 87 id: this.todoList.length, 88 content: this.addDoingThings, 89 isDone: false 90 }) 91 this.addDoingThings = "" 92 this.saveData() 93 }, 94 //保存数据到本地存储 95 saveData: function () { 96 localStorage.todoList = JSON.stringify(this.todoList) 97 }, 98 //选择做完的事情 99 checkDoneThings: function (id) { 100 this.todoList[id].isDone = !this.todoList[id].isDone; 101 //每次修改后要保存 102 this.saveData(); 103 }, 104 //删除任务 105 delThings: function (id) { 106 this.todoList.splice(id, 1) 107 this.todoList.forEach(function (item, i) { 108 item.id = i 109 }) 110 //每次修改后要保存 111 this.saveData(); 112 } 113 } 114 }); 115 </script> 116 </body> 117 </html>
1 body { 2 margin: 0; 3 padding: 0; 4 font-size: 16px; 5 background: #cdcdcd; 6 } 7 8 a { 9 text-decoration: none; 10 } 11 12 header { 13 height: 50px; 14 background: #333; 15 background: rgba(47, 47, 47, 0.98); 16 } 17 18 section { 19 margin: 0 auto; 20 } 21 22 label { 23 float: left; 24 width: 100px; 25 line-height: 50px; 26 color: #ddd; 27 font-size: 24px; 28 cursor: pointer; 29 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 30 } 31 32 header input { 33 float: right; 34 width: 60%; 35 height: 24px; 36 margin-top: 12px; 37 text-indent: 10px; 38 border-radius: 5px; 39 box-shadow: 0 1px 0 rgba(255, 255, 255, 0.24), 40 0 1px 6px rgba(0, 0, 0, 0.45) inset; 41 border: none; 42 } 43 44 input:focus { 45 outline-width: 0; 46 } 47 48 h2 { 49 position: relative; 50 } 51 52 .doingItem, 53 .doneItem { 54 display: flex; 55 } 56 57 .doingItem span, 58 .doneItem span { 59 flex: 10; 60 display: inline-block; 61 padding: 0 5px; 62 text-align: left; 63 color: #666; 64 font-size: 14px; 65 } 66 67 .doingItem input, 68 .doneItem input { 69 width: 22px; 70 height: 22px; 71 cursor: pointer; 72 align-self: center; 73 } 74 75 p { 76 margin: 0; 77 } 78 79 .doingItem p input, 80 .doneItem p input { 81 top: 3px; 82 left: 40px; 83 width: 70%; 84 height: 20px; 85 line-height: 14px; 86 text-indent: 5px; 87 font-size: 14px; 88 } 89 90 .doingItem, 91 .doneItem { 92 height: 32px; 93 line-height: 32px; 94 background: #fff; 95 position: relative; 96 margin-bottom: 10px; 97 padding: 0 10px; 98 border-radius: 3px; 99 border-left: 5px solid #629a9c; 100 box-shadow: 0 1px 2px rgba(0, 0, 0, 0.07); 101 } 102 103 .doneItem { 104 border-left: 5px solid #666; 105 } 106 107 .doingItem a.delBtn, 108 .doneItem a.delBtn { 109 display: inline-block; 110 line-height: 18px; 111 width: 22px; 112 height: 22px; 113 border-radius: 14px; 114 text-align: center; 115 background: #f1f1f1; 116 color: #666; 117 font-size: 28px; 118 cursor: pointer; 119 align-self: center; 120 } 121 122 footer { 123 color: #666; 124 font-size: 14px; 125 text-align: center; 126 } 127 128 footer a { 129 color: #666; 130 text-decoration: none; 131 color: #999; 132 } 133 134 @media screen and (max-device-width: 620px) { 135 section { 136 width: 96%; 137 padding: 0 2%; 138 } 139 } 140 141 @media screen and (min-width: 620px) { 142 section { 143 width: 600px; 144 padding: 0 10px; 145 } 146 }
原文地址:https://www.cnblogs.com/rchi/p/12659374.html
时间: 2024-10-04 12:40:44