Vue 实现ToDoList
【摘要】
Vue 实现ToDoList
本文实现一个用Vue脚手架搭建项目、实现简单的ToDoList功能
computed:计算属性filters:过滤器localStorage:本地存储
技术点 vue+...
Vue 实现ToDoList
本文实现一个用Vue脚手架搭建项目、实现简单的ToDoList功能
- computed:计算属性
- filters:过滤器
- localStorage:本地存储
技术点
vue+localStorage
功能
回车添加任务
双击编辑任务
编辑完成按回车保存 Esc撤销编辑
点击复选框表示已经完成任务
点击X删除任务
所有任务、已经完成任务、未完成任务可筛选
具体代码演示如下
<template>
<div>
<header>
<section>
<label for="title"> ToDoList</label>
<input type="text" id="title" placeholder="添加ToDo" v-model="iptVal" @keydown.13="add">
</section>
</header>
<h3>未完成({{no}})</h3>
<ul>
<li v-for="(item,index) in list" :key="index" v-show="!item.done">
<input type="checkbox" @click.prevent="change(item,true)">
<span v-if="index !== iptIndex" @dblclick="update(item,index)">{{item.val}}</span>
<input
v-if="index === iptIndex"
type="text"
v-model="item.val"
@keydown.enter="enter(item,index)"
autofocus
@keydown.esc="esc(item,index)"
>
<span class="time">{{item.time | timeFilter}}</span>
<span @click="del(index)" class="del">×</span>
</li>
</ul>
<h3>已经完成({{yes}})</h3>
<ul>
<li v-for="(item,index) in list" :key="index" v-show="item.done">
<input type="checkbox" checked @click.prevent="change(item,false)">
<span v-if="index !== iptIndex" @dblclick="update(item,index)">{{item.val}}</span>
<input
v-if="index === iptIndex"
type="text"
v-model="item.val"
@keydown.enter="enter(item,index)"
autofocus
@keydown.esc="esc(item,index)"
>
<span class="time">{{item.time | timeFilter}}</span>
<span @click="del(index)" class="del">×</span>
</li>
</ul>
<footer>
<select v-model="select" @change="selected">
<option value="">请选择</option>
<option value="all">全部数据</option>
<option value="no">未完成</option>
<option value="yes">已完成</option>
</select>
<ul>
<li v-for="(item,index) in selist" :key="index">
{{item.val}}
</li>
</ul>
</footer>
</div>
</template>
<script>
export default {
//计算属性 用来计算已完成 未完成的数量
computed: {
no() {
let n = 0;
this.list.map(item => {
if (!item.done) {
n++;
}
});
return n;
},
yes() {
let n = 0;
this.list.map(item => {
if (item.done) {
n++;
}
});
return n;
}
},
//时间过滤
filters: {
timeFilter(ms) {
let time = new Date();
let nowTime = time.getTime(); //现在时间的
let cha = nowTime - ms; //差值
let months = cha / 1000 / 60 / 60 / 24 / 30;
let week = cha / 1000 / 60 / 60 / 24 / 7;
let days = cha / 1000 / 60 / 60 / 24;
let hours = cha / 1000 / 60 / 60;
let minutes = cha / 1000 / 60;
let str = '';
if (months >= 1) {
str = `${parseInt(months)}月前`
} else if (week >= 1) {
str = `${parseInt(week)}周前`
} else if (days >= 1) {
str = `${parseInt(days)}天前`
} else if (hours >= 1) {
str = `${parseInt(hours)}小时前`
} else if (minutes >= 1) {
str = `${parseInt(minutes)}分钟前`
} else {
str = '刚刚'
}
return str;
}
},
data() {
return {
list: JSON.parse(localStorage.getItem('six')) || [],
iptVal: "", //输入框的值
iptIndex: -1, //设置一个固定值 用来实现双击显示和隐藏
temp: '', //声明一个空值用来保存esc取消时的数据
select: '', //筛选 输入框改变时 存储 yes no all
selist: [], //筛选数据的展示
}
},
methods: {
add() {
this.list.push({
val: this.iptVal,
done: false, //每增加一条数据 done 为false
time: new Date().getTime() //每增加一条新数据,增加对应的时间戳
});
this.save(); // 同步保存到本地存储
this.iptVal = '';
},
save() { //本地存储
localStorage.six = JSON.stringify(this.list)
},
//删除
del(index) {
this.list.splice(index, 1);
this.save()
},
// 双击改变
update(item, index) {
this.iptIndex = index;
//给temp 赋值 值为item.val
this.temp = item.val;
},
//按回车 保存数据
enter(item, index) {
this.save(); //先保存到本地存储 顺序不能变
this.list.splice(index, 1, item); //页面展示的数据改变
this.iptIndex = -1; //iptIndex值还原,让input框隐藏
},
//按ESC取消
esc(item, index) {
item.val = this.temp; //现在temp里已经有值 然后再赋值给item.val
this.iptIndex = -1; //iptIndex值还原,让input框隐藏
},
//点击复选框改变 未完成改为已完成 已完成改为未完成
change(item, checked) {
item.done = !!checked;
this.save()
},
//筛选
selected() {
// console.log(this.select);
this.selist = []; //清空数组里的值,不然每次都追加
switch (this.select) {
case "all": //全部 展示
this.list.map(item => { //遍历
this.selist.push(item) //添加到selist数组
});
break;
case "no": //未完成展示
this.list.map(item => { //遍历
if (!item.done) {
this.selist.push(item) //添加到selist数组
}
});
break;
case "yes": //已完成展示
this.list.map(item => { //遍历
if (item.done) {
this.selist.push(item) //添加到selist数组
}
});
break;
}
}
}
}
</script>
<style>
header {
height: 50px;
background: rgba(47, 47, 47, 0.98);
}
.time {
color: #dddddd;
margin-left: 10px;
}
section {
width: 600px;
padding: 0 10px;
display: flex;
margin: 0 auto;
}
label {
float: left;
width: 100px;
line-height: 50px;
color: #DDD;
font-size: 24px;
cursor: pointer;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.del {
color: red;
margin-left: 50px;
}
header input {
float: right;
width: 60%;
height: 24px;
margin-top: 12px;
text-indent: 10px;
border-radius: 5px;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.24), 0 1px 6px rgba(0, 0, 0, 0.45) inset;
border: none;
outline: none;
margin-left: 10px;
}
</style>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
文章来源: lvsige.blog.csdn.net,作者:祥子的小迷妹,版权归原作者所有,如需转载,请联系作者。
原文链接:lvsige.blog.csdn.net/article/details/106547778
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)